프론트 페이지 경로 프로세서에 대한 캐싱 비활성화

Nov 18 2020

저는 사용자가 책 (핵심 기능)을 만들 수있는 프로젝트를 진행하고 있습니다. 간단한 텍스트 필드에서 도메인을이 책에 연결할 수 있습니다. 이렇게하면이 도메인을 통해서만 책에 액세스 할 수 있습니다.

예를 들어 Book A경로 node\1와 도메인이 a.book.com있습니다. 나는 또한 Book B경로 node\2와 도메인에 연결되어 있습니다 b.book.com.

내가 지금 원하는 것은 방문자가 a.book.com프론트 페이지에 가면 입니다 node/1. 그리고 그들이 b.book.com프론트 페이지 로 가면 node/2? 이에 대한 사용자 지정 모듈을 만들었습니다 book_frontpage.

이를 위해 PathProcessorFront.php코어에서 많은 부분을 사용했습니다 .

내 코드 book_front.services.yml는 다음과 같습니다.

services:
  book_frontpage.path_processor_front:
    class: Drupal\book_frontpage\PathProcessor\FrontPagePathProcessor
    tags:
      - { name: path_processor_inbound, priority: 300 }

내 코드 FrontPagePathProcessor.php는 다음과 같습니다.

<?php

namespace Drupal\book_frontpage\PathProcessor;

use Drupal\Core\Database\Database;
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Path processor to replace 'node' with 'content' in URLs.
 */
class FrontPagePathProcessor implements InboundPathProcessorInterface{
  /**
   * {@inheritdoc}
   */
  public function processInbound($path, Request $request)
  {
    if ($path === '/') { //current domain $currentDomain = $_SERVER['SERVER_NAME']; //get nid of reader where domain is set $nid = Database::getConnection()->select('node__field_domain', 'd')
        ->fields('d', ['entity_id'])
        ->condition('field_domain_value', $currentDomain, '=') ->execute() ->fetchField(); //get path $path = \Drupal::service('path_alias.manager')->getAliasByPath('/node/'. $nid); if (empty($path)) {
        // We have to return a valid path but / won't be routable and config
        // might be broken so stop execution.
        throw new NotFoundHttpException();
      }
      $components = parse_url($path);

      // Remove query string and fragment.
      $path = $components['path'];

      // Merge query parameters from front page configuration value
      // with URL query, so that actual URL takes precedence.
      if (!empty($components['query'])) { parse_str($components['query'], $parameters); array_replace($parameters, $request->query->all()); $request->query->replace($parameters); } } return $path;
  }
}

이제 a.book.com보러 node/1b.book.com때도 봅니다 node/1. 캐시를 지우고 처음으로 가면 b.book.com얻을 수 node/2있지만 a.book.com가면 node/2. 그래서 이것은 캐시 문제처럼 보입니다.

이 프론트 페이지 경로의 캐싱을 어떻게 비활성화 할 수 있습니까?

답변

4 4k4 Nov 18 2020 at 17:34

여기서 논의한 것처럼, Hide path on frontpage redirect , 경로 컬렉션의 캐싱을 도메인별로 만들어야합니다. 논의 된 핵심 서비스 재정의 외에 Drupal 8.8부터 서비스 메서드 addExtraCacheKeyPart ()를 사용할 수 있습니다 .

요청 이벤트 구독자에 다음 코드를 추가하십시오.

/src/EventSubscriber/RouteCacheDomainSubscriber.php

<?php

namespace Drupal\mymodule\EventSubscriber;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RouteCacheDomainSubscriber implements EventSubscriberInterface {
  
  public function onKernelRequest(GetResponseEvent $event) { $routeProvider = \Drupal::service('router.route_provider');
    $domain = \Drupal::request()->getHost(); $routeProvider->addExtraCacheKeyPart('domain', $domain); } /** * {@inheritDoc} */ public static function getSubscribedEvents() { // run before RouterListener (priority 32) $events[KernelEvents::REQUEST][] = ['onKernelRequest', 33];
    return $events;
  }

}

mymodule.services.yml

services:
  mymodule.route_cache_domain_subscriber:
    class: Drupal\mymodule\EventSubscriber\RouteCacheDomainSubscriber
    arguments: []
    tags:
      - { name: event_subscriber }

또한 route_match북 노드를 저장할 때 캐시 태그를 무효화해야합니다 . 라우터를 부분적으로 재 구축하거나 경로 캐시를 무효화하는 방법이 있습니까?를 참조하십시오 .