基于Group模块按用户组身份切换群组视图模式的技术问询
Great question! You're on the right track with using a route subscriber—you don't need to rebuild the entire controller just to switch view modes based on whether the current user is a group member. Below are two elegant approaches to implement this in Drupal:
Approach 1: Use a Route Enhancer (Recommended)
Route enhancers let you dynamically modify route defaults at runtime, which is perfect for swapping view modes without touching the core controller.
Step 1: Update Your Route Subscriber
Modify your existing route subscriber to attach a custom enhancer to the entity.group.canonical route:
protected function alterRoutes(RouteCollection $collection) { if ($route = $collection->get('entity.group.canonical')) { // Add our custom route enhancer to the route's enhancer list $existing_enhancers = $route->getOption('_route_enhancers') ?: []; $route->setOption('_route_enhancers', array_merge($existing_enhancers, [ 'your_module.group_view_mode_enhancer' ])); } }
Step 2: Define the Route Enhancer Service
Add this to your module's your_module.services.yml file to register the enhancer:
services: your_module.group_view_mode_enhancer: class: Drupal\your_module\RouteEnhancer\GroupViewModeEnhancer arguments: ['@current_user'] tags: - { name: route_enhancer }
Step 3: Implement the Route Enhancer Class
Create the GroupViewModeEnhancer class to check membership and switch view modes:
namespace Drupal\your_module\RouteEnhancer; use Drupal\Core\Routing\RouteEnhancerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\group\Entity\GroupInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Route; class GroupViewModeEnhancer implements RouteEnhancerInterface { protected $currentUser; public function __construct(AccountInterface $current_user) { $this->currentUser = $current_user; } public function enhance(array $defaults, Request $request) { // Only proceed if we have a valid group entity in the route if (isset($defaults['group']) && $defaults['group'] instanceof GroupInterface) { /** @var GroupInterface $group */ $group = $defaults['group']; // Check if current user is a group member $is_member = $group->getMember($this->currentUser) !== NULL; // Swap view mode (replace with your custom view mode machine names) $defaults['_entity_view']['group'] = $is_member ? 'member_view' : 'non_member_view'; } return $defaults; } public function applies(Route $route) { // Only apply this enhancer to the group canonical route return $route->getPath() === '/group/{group}'; } }
Approach 2: Extend the Core Entity View Controller
If you prefer a more explicit approach, you can extend Drupal's core EntityViewController and override the view method to switch modes:
Step 1: Update Your Route Subscriber
Replace the controller for the group canonical route with your custom one:
protected function alterRoutes(RouteCollection $collection) { if ($route = $collection->get('entity.group.canonical')) { // Swap the core controller with our extended version $route->setDefault('_controller', '\Drupal\your_module\Controller\GroupViewController::view'); } }
Step 2: Implement the Custom Controller
Create the controller class that inherits from the core controller and modifies the view mode:
namespace Drupal\your_module\Controller; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityViewController; use Drupal\Core\Session\AccountInterface; use Drupal\group\Entity\GroupInterface; use Symfony\Component\DependencyInjection\ContainerInterface; class GroupViewController extends EntityViewController { protected $currentUser; public static function create(ContainerInterface $container) { $instance = parent::create($container); $instance->currentUser = $container->get('current_user'); return $instance; } public function view(EntityInterface $group, $view_mode = 'full', $langcode = NULL) { if ($group instanceof GroupInterface) { // Check membership and override view mode $is_member = $group->getMember($this->currentUser) !== NULL; $view_mode = $is_member ? 'member_view' : 'non_member_view'; } // Pass control back to the core controller with our updated view mode return parent::view($group, $view_mode, $langcode); } }
Final Setup Notes
- Create Custom View Modes: Go to
/admin/structure/group/manage/[group-type]/displayto create yourmember_viewandnon_member_viewview modes, then configure which fields show up in each. - Clear Cache: Don't forget to clear Drupal's cache after adding the code and view modes.
Both approaches let you reuse core functionality while dynamically switching the view mode based on group membership—no need to build a controller from scratch!
内容的提问来源于stack exchange,提问作者Jonathan

