Problem/Motivation

When using the batch export method in combination with a path that starts with admin/ it is expected that the admin theme would be active and used for the batch export.

Currently the batch will use the default theme instead of the admin theme, as neither Drupal\views_data_export\Plugin\views\display\DataExport::collectRoutes (via parent Drupal\rest\Plugin\views\display\RestExport::collectRoutes) nor Drupal\system\EventSubscriber\AdminRouteSubscriber::alterRoutes set the route option _admin_route - which is used to determine the active theme.

Steps to reproduce

I have only tested this with 9.5

  1. Install Drupal using core profile
  2. Enable views_data_export
  3. Add a Data Export display to the content view, use Method: Batch under export settings and use admin/content/export (or any path beginning with admin) as the path.
  4. Visit /admin/content/export
  5. Observe the batch process is using the site theme, not the admin theme

From debugging we can see

When the routes are built:

  1. Drupal\rest\Plugin\views\display\RestExport::collectRoutes returns the route object with _format set to the export format selected in "Accepted request formats" in the view (e.g csv)
  2. AdminRouteSubscriber::isHtmlRoute returns FALSE and so does not mark this as an admin route - it does this by checking the _format requirement of the route to see if it has the html format. In this case, the format is csv as so it does not get marked as an admin route

When the request is handled:

  1. \Drupal\user\Theme\AdminNegotiator does not apply as the Drupal\Core\Routing\AdminContext::isAdminRoute returns FALSE for the route
  2. DataExport::buildBatch calls batch_process which calls \Drupal::theme()->getActiveTheme()->getName() to set the theme for the batch - which is not the admin theme due to the above conditions.

Proposed resolution

I believe if batch it in use, it is expected behaviour that using an admin path /admin should use the admin theme.

This would involve the DataExport plugin overriding the collectRoutes method to mark the route as an admin route if the batch export method is used and the path starts with admin.

Remaining tasks

  1. Agree on approach
  2. Patch
  3. Review

User interface changes

TBC

API changes

TBC

Data model changes

TBC

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

ericgsmith created an issue. See original summary.

ericgsmith’s picture

StatusFileSize
new17.41 KB

Uploading example views.view.content.yml file with a json export attached to the default content view which can be used for testing.

ericgsmith’s picture

Another option would be to add an additional option such as in https://www.drupal.org/project/drupal/issues/2719797 / https://git.drupalcode.org/project/drupal/-/commit/4dbf3f46c19766a38c3e4... to be able to mark the path as an admin route directly in views UI.

In that plugin, if the path start with /admin it is showing "Yes (admin path)" - so perhaps instead of changing the formats on the route, the plugin can just mark the route as admin directly if the path starts with admin?

ericgsmith’s picture

Issue summary: View changes
ericgsmith’s picture

Issue summary: View changes
ericgsmith’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new1.37 KB

Patch going with the option of marking the route as an admin route.

Setting as needs review to get feedback on the approach - we should be able to add a unit test to test the route collection.

ericgsmith’s picture

Went for a kernel test so that the test can still be valid if the implementation differs from the proposed approach.

Interdiff is the test only patch.

rosk0’s picture

Status: Needs review » Reviewed & tested by the community

Thanks Eric!

Looks good to me - approach is sensible, and fixes our unexpected behaviour with front theme on admin path.

tanmayk’s picture

Thanks for the patch. It fixes the problem.

lexsoft’s picture

+1 to get this committed

mibfire’s picture

Actually the "batch" path should always use the admin theme regardless of views path starts with "/admin" or not, because this is also the case in the core:

system.batch_page.json:
  path: '/batch'
  defaults:
    _controller: '\Drupal\system\Controller\BatchController::batchPage'
  requirements:
    _access: 'TRUE'
    _format: 'json'
  options:
    _admin_route: TRUE

So here the batch uses always the admin theme and this should be the case with the patch for this issue. I removed the

str_starts_with($this->getOption('path') ?? '', 'admin/')

part from the patch.

Status: Reviewed & tested by the community » Needs work
ericgsmith’s picture

Status: Needs work » Needs review

Actually the "batch" path should always use the admin theme regardless of views path starts with "/admin" or not, because this is also the case in the core:

This is not true and is not the case in core.

The batch negotiator (theme.negotiator.system.batch) runs at a higher priority that the admin theme negotiator (theme.negotiator.admin_theme)

See https://git.drupalcode.org/project/drupal/-/blob/11.x/core/modules/syste...

mibfire’s picture

@ericgsmith

Indeed, you are right. Thanks! I hid my patch.

erom’s picture

this patch works for me.

erom’s picture

StatusFileSize
new1.37 KB
ericgsmith’s picture

Can you please explain your patch @erom?

If you are making changes to a patch you should supply interdiff and comment on the changes or its confusing to follow.

I've only glanced at it but it looks like the patch in 7 but without the test?

erom’s picture

@ericgsmith, my patch will just automatically use the admin theme when it's using the batch. it is not logically correct since some use cases should allow batch to appear within a theme, i will hide my patch..

besek’s picture

I've tested patch #17 on Drupal 10.2.6 with Views Data Export 8.x-1.4 and it works really nice, thanks @erom.

ericgsmith’s picture

Moved patch #7 to MR

This was previously RTBC'd in #9 and #10 and #11 but subsequent patches were added which moved it back to needs work / review.

I'm incline to argue the subsequent changes to the patch have not been needed and the tests were lost - I'm leaving this as needs review.

goodmood’s picture

After module update to 1.5 patch #7 can't be applied anymore. Adding re-rolled patch while MR is in review

dennisdk’s picture

#23 works as expected for us on 1.5.0

c_archer’s picture

Status: Needs review » Reviewed & tested by the community

Patch #23 works well with no issues.

steven jones’s picture

Assigned: Unassigned » steven jones
Status: Reviewed & tested by the community » Needs work

Looking at this now, we already provide the route and change some options on it, so we don't need to alter our own route I don't think.

steven jones’s picture

steven jones’s picture

Status: Needs work » Reviewed & tested by the community

@ericgsmith thanks so much for the issue, code and the tests, super helpful.

I've basically committed what you had, but in our method that generates the original route, rather than altering the collection of them. Seems to work fine, and your tests still pass :)

  • steven jones committed fcafcfea on 8.x-1.x
    Issue #3368855 by steven jones: Set the admin path option on routes.
    

steven jones’s picture

Status: Reviewed & tested by the community » Fixed

Thanks everyone!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

recrit’s picture

If anyone got to this issue and wondered why your views data export display is still showing in the front end theme instead of the admin theme, it is most likely because your view path does not start with "/admin". This is because the change for this issue only targeted those paths - see https://git.drupalcode.org/project/views_data_export/-/commit/fcafcfeac3....

This can be fixed in your build by implementing a route subscriber. See https://www.drupal.org/docs/drupal-apis/routing-system/altering-existing... for details on how to create one.

Example: The following will set all "data_export" views displays to use the admin theme.


namespace Drupal\your_custom_module\Routing;

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

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

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    foreach ($collection->all() as $name => $route) {
      // Set all views_data_export diplays to use the admin theme.
      if (str_starts_with($name, 'view.') &&
          ($display_plugin_id = $route->getOption('_view_display_plugin_id')) &&
          $display_plugin_id === 'data_export') {
        $route->setOption('_admin_route', TRUE);
      }
    }
  }

}