A Drupal 8 block plugin which needs to be shown only on node pages (using route matcher)
<?php | |
namespace Drupal\my_module\Plugin\Block; | |
use Drupal\Core\Access\AccessResult; | |
use Drupal\Core\Block\BlockBase; | |
use Drupal\Core\Cache\Cache; | |
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; | |
use Drupal\Core\Routing\RouteMatchInterface; | |
use Drupal\Core\Session\AccountInterface; | |
use Drupal\node\NodeInterface; | |
use Drupal\my_lists\ProfilesService; | |
use Symfony\Component\DependencyInjection\ContainerInterface; | |
/** | |
* Provides a 'TextAdsBlock' block. | |
* | |
* @Block( | |
* id = "text_ads", | |
* admin_label = @Translation("Text Ads"), | |
* category = @Translation("Ads") | |
* ) | |
*/ | |
class TextAdsBlock extends BlockBase implements ContainerFactoryPluginInterface { | |
/** | |
* Drupal\my_lists\ProfilesService definition. | |
* | |
* @var \Drupal\my_lists\ProfilesService | |
*/ | |
protected $profilesService; | |
protected $routeMatch; | |
protected function getNode() { | |
$obj = $this->routeMatch->getParameter('node'); | |
if (!$obj instanceof NodeInterface) { | |
throw new \UnexpectedValueException("Not a node page"); | |
} | |
if ($obj->bundle() !== 'article') { | |
throw new \UnexpectedValueException("Not an article node"); | |
} | |
return $obj; | |
} | |
protected function blockAccess(AccountInterface $account) { | |
try { | |
$node = $this->getNode(); | |
} | |
catch (\UnexpectedValueException $ex) { | |
return AccessResult::forbidden(); | |
} | |
return parent::blockAccess($account); | |
} | |
public function __construct( | |
array $configuration, | |
$plugin_id, | |
$plugin_definition, | |
ProfilesService $profiles_service, | |
RouteMatchInterface $route_match | |
) { | |
parent::__construct($configuration, $plugin_id, $plugin_definition); | |
$this->profilesService = $profiles_service; | |
$this->routeMatch = $route_match; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { | |
return new static( | |
$configuration, | |
$plugin_id, | |
$plugin_definition, | |
$container->get('my_lists.profiles'), | |
$container->get('current_route_match') | |
); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function build() { | |
// TODO: Filter the profiles based on current node type and location. | |
$profiles = array_slice($this->profilesService->getProfiles(), 0, 15); | |
$build = [ | |
'#theme' => 'my_text_ads', | |
'#profiles' => $profiles, | |
]; | |
return $build; | |
} | |
public function getCacheTags() { | |
$node = $this->getNode(); | |
return Cache::mergeTags(parent::getCacheTags(), ['node:' . $node->id()]); | |
} | |
public function getCacheContexts() { | |
return Cache::mergeContexts(parent::getCacheContexts(), ['route']); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment