이는 매우 기본 블록의 필요에 맞는 계획을 선택합니다 현재 노드's ID 입니다.
<?php
/**
* @file
* Contains \Drupal\mymodule\Plugin\Block\ExampleEmptyBlock.
*/
namespace Drupal\mymodule\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
/**
* @Block(
* id = "example_empty",
* admin_label = @Translation("Example: empty block")
* )
*/
class ExampleEmptyBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$node = \Drupal::routeMatch()->getParameter('node');
$build = array();
if ($node) {
$config = \Drupal::config('system.site');
$build = array(
'#type' => 'markup',
'#markup' => '<p>' . $node->id() . '<p>',
'#cache' => array(
'tags' => $this->getCacheTags(),
'contexts' => $this->getCacheContexts(),
),
);
}
return $build;
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
$node = \Drupal::routeMatch()->getParameter('node');
return Cache::mergeTags(parent::getCacheTags(), ["node:{$node->id()}"]);
}
/**
* {@inheritdoc}
*/
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['user.node_grants:view']);
}
}
하지만 일단 캐시록 동일하게 유지에 관계없이는 노드가 방문합니다. 어떻게 올바르게 캐시 결과 노드당 ID?
이것은 전체 작업 코드를 가진다.
namespace Drupal\module_name\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
/**
* Provides a Node cached block that display node's ID.
*
* @Block(
* id = "node_cached_block",
* admin_label = @Translation("Node Cached")
* )
*/
class NodeCachedBlock extends BlockBase {
public function build() {
$build = array();
//if node is found from routeMatch create a markup with node ID's.
if ($node = \Drupal::routeMatch()->getParameter('node')) {
$build['node_id'] = array(
'#markup' => '<p>' . $node->id() . '<p>',
);
}
return $build;
}
public function getCacheTags() {
//With this when your node change your block will rebuild
if ($node = \Drupal::routeMatch()->getParameter('node')) {
//if there is node add its cachetag
return Cache::mergeTags(parent::getCacheTags(), array('node:' . $node->id()));
} else {
//Return default tags instead.
return parent::getCacheTags();
}
}
public function getCacheContexts() {
//if you depends on \Drupal::routeMatch()
//you must set context of this block with 'route' context tag.
//Every new route this block will rebuild
return Cache::mergeContexts(parent::getCacheContexts(), array('route'));
}
}
나는 그것을 테스트;그것은 작동합니다.
그냥 넣어 코드 라는 이름의 파일 NodeCachedBlock.php 모듈에서 폴더를 변경,네임스페이스의{module_name},캐시고 그것을 사용할 수 있습니다.
하여 이 작업을 수행하는 가장 쉬운 방법은에 의존하는 것 플러그인을 차단하는 컨텍스트 시스템입니다.
당신은 그냥 넣어 가지고 있는 노드를 정의 컨텍스트에서 당신의 블록 주석을 다음과 같다:
* context = {
* "node" = @ContextDefinition("entity:node", label = @Translation("Node"))
* }
고 그것을 사용하는 이 같은$이->getContextValue('node')
좋은 점은 Drupal 을 다음의 캐싱한다. 자동으로 합니다. 기 때문에 그것이 알고 있는 기본(지금까지와 같은 핵심 간만)노드황은 현재 노드입니다. 고 알고있는 곳에서 나오는,그래서 캐시텍스트 및 캐시 태그가 자동으로 추가됩니다.
을 통해\Drupal\핵심\플러그인\ContextAwarePluginBase::getCacheContexts()
와 해당하는`getCacheTags()메소,BlockBase/블록 확장 클래스에서는 상속 그 방법이 있습니다.
파생하는 경우 클래스의 블록에서 플러그인Drupal\핵심\블록\BlockBase
,당신은 당신을 설정하는 방법에는 두 가지 캐시 태그 및 상황.
-getCacheTags()
-getCacheContexts()
예를 들어 책의 블록 모듈이 구현하는 그 방법은 다음과 같습니다.
/**
* {@inheritdoc}
*/
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['route.book_navigation']);
}
포럼 모듈 블록을 사용하는 다음의 코드입니다.
/**
* {@inheritdoc}
*/
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['user.node_grants:view']);
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return Cache::mergeTags(parent::getCacheTags(), ['node_list']);
}
귀하의 경우에,나는 다음 코드를 사용합니다.
/**
* {@inheritdoc}
*/
public function getCacheTags() {
$node = \Drupal::routeMatch()->getParameter('node');
return Cache::mergeTags(parent::getCacheTags(), ["node:{$node->id()}"]);
}
당신은 또한 다음과 같은 방법을 사용 블록을 만들 uncacheable 에서는 모두(는 경우에도 나는 그것을 피하). 그것은 도움이 될 수 있 다른 경우에는,아마도.
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
return 0;
}
을 기억하는가사용 Drupal\핵심\캐시\캐시에서
최고의 파일 경우,당신은 당신을 사용하려캐시
클래스입니다.
을 추가하려면#캐시
에서 노드를 자동으로:
use Drupal\Core\Cache\Cache;
$build = array(
...
'#cache' => array(
'tags' => Cache::mergeTags($this->getCacheTags(), $node->getCacheTags()),
'contexts' => $node->getCacheContexts(),
'max-age' => $node->getCacheMaxAge(),
),
);
컨텍스트의 중요한 중 하나는 여기에.
을 설정하는 컨텍스트를 수동:
$build = array(
...
'#cache' => array(
'contexts' => array('url.path'),
),
);
여기서 문제는 캐시 컨텍스트를 선언하지 않을 장소에서 빌드 기능:
class ExampleEmptyBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$node = \Drupal::routeMatch()->getParameter('node');
$build = array();
if ($node) {
$config = \Drupal::config('system.site');
$build = array(
'#type' => 'markup',
'#markup' => '<p>' . $node->id() . '<p>',
'#cache' => array(
'tags' => $this->getCacheTags(),
'contexts' => $this->getCacheContexts(),
),
);
}
return $build;
}
}
를 호출하는 경우는 블록에 비 노드,빌드 기능을 빈 배열을 반환,이 없다 그래서 캐시텍스트를 이 블록고는 행동에 의해 캐시됩 drupal:의 디스플레이 막지 않을 것이 제대로 무효화 또는 렌더링됩니다.
솔루션을 초기화$으로 구축 캐시 컨텍스트 마다:
class ExampleEmptyBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$node = \Drupal::routeMatch()->getParameter('node');
$build = array(
'#cache' => array(
'tags' => $this->getCacheTags(),
'contexts' => $this->getCacheContexts(),
),
);
if ($node) {
$config = \Drupal::config('system.site');
$build['#markup'] = '<p>' . $node->id() . '<p>';
$build['#type'] = 'markup';
}
return $build;
}
}
나는 나는'm 늦게 이런 대화만,아래 코드는 나를 위해 일했:
class ExampleBlock extends BlockBase
{
public function build()
{
$lcContent = '';
$loNode = \Drupal::routeMatch()->getParameter('node');
if (!$loNode)
{
return (array(
'#type' => 'markup',
'#cache' => array('max-age' => 0),
'#markup' => $lcContent,
));
}
$lcContent .= "<div id='example_block' style='overflow: hidden; clear: both;'>\n";
$lcContent .= $loNode->id();
$lcContent .= "</div>\n";
return (array(
'#type' => 'markup',
'#cache' => array('max-age' => 0),
'#markup' => $lcContent,
));
}
}