Header, Footer, Empty areas

Created on 4 August 2023, 11 months ago
Updated 28 November 2023, 7 months ago

Problem/Motivation

The core Rest Export display is set to not allow area plugins. This is what disables header, footer, and empty areas of a View from being populated. For decoupled or hybrid approaches, you may want to indicate what should be in the header or footer area of the interface, especially any empty result text or behavior. There likely are limitations on what can be done, but the general use case would be largely text, maybe links.

Proposed resolution

Explore creating a PathPluginBase similar to RestExport that does allow for area plugins to be configured, then add them into the response output.

A quick test:

There may be technical issues that make this difficult to do, but is worth looking at. No results behavior could then be controlled from Drupal, instead of hard coding it in any JS implementation.

πŸ’¬ Support request
Status

Needs work

Version

1.0

Component

User interface

Created by

πŸ‡ΊπŸ‡ΈUnited States kevinquillen

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @kevinquillen
  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen
  • Assigned to kevinquillen
  • Status changed to Needs work 7 months ago
  • πŸ‡ΊπŸ‡Έ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:

  • πŸ‡ΊπŸ‡Έ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.

Production build 0.69.0 2024