How do I get the current node from a Block module? I'm looking to create a block that renders differently, depending on the content (metadata, really) of the node in which it is embedded.

The “Title” block is a good example of what I'm trying to do, I think. When you put “Page title” in a section (from the Structure menu), it displays the title of the node being displayed.

I'd like to do something similar. The end goal is to read the workflow state data from the node in order to provide large visual clues to readers that the document they are reading is approved/unapproved/et cetera.

There are some other similar ends to which I may put this technique as well, provided I figure it out.

Here's what I have:

/**
 * Provides a 'Workflow Block'.
 *
 * @Block(
 *   id = "workflow_tag_block",
 *   admin_label = @Translation("Workflow Block"),
 * )
 */
class WorkflowTagBlock extends BlockBase implements ContainerFactoryPluginInterface {
        protected $node;

        public function __construct(array $configuration, $plugin_id, $plugin_definition, $node) {
                parent::__construct($configuration, $plugin_id, $plugin_definition);

                $this-&gt;node = $node;
        }

        public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
                return new static(
                        $configuration,
                        $plugin_id,
                        $plugin_definition,
                        $container-&gt;get /*... something here, I think. I need this to be the node I'm rendering. */
                );
        }

        /**
         * {@inheritdoc}
         */
        public function build() {
                // do things with $this-&gt;node;

                return [
                        '#markup' =&gt; $this-&gt;t('Here Be Dragons! '),
                ];
        }
}


Obviously, there's an important line I don't have complete in there. The most obvious attempt would be: $container-&gt;get('request_stack')-&gt;getCurrentRequest()-&gt;get('node'). But that returns the WorkflowTagBlock object itself, not the primary content node.

I'm aware that multiple nodes might be rendered on the screen at once (for example, in a list), so I can't just try to snag the node id from the uri or anything like that.

This is done in other places, so surely there's a way to do it. How?
The Book module implements a block that needs to access to the currently viewed node, and it uses the following code, in BookNavigationBlock::build().

if ($node = $this-&gt;requestStack-&gt;getCurrentRequest()-&gt;get('node')) {
  $current_bid = empty($node-&gt;book['bid']) ? 0 : $node-&gt;book['bid'];
}


$this-&gt;requestStack is initialized from the following code.

  public function __construct(array $configuration, $plugin_id, $plugin_definition, RequestStack $request_stack, BookManagerInterface $book_manager, EntityStorageInterface $node_storage) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this-&gt;requestStack = $request_stack;
    $this-&gt;bookManager = $book_manager;
    $this-&gt;nodeStorage = $node_storage;
  }

  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
    $configuration, 
    $plugin_id, 
    $plugin_definition, 
    $container-&gt;get('request_stack'), 
    $container-&gt;get('book.manager'), 
    $container-&gt;get('entity.manager')-&gt;getStorage('node')
    );
  }


The code is essentially like the one you are using, but it seems that in your case, a module is messing up with what $container-&gt;get('request_stack')-&gt;getCurrentRequest()-&gt;get('node') is returning. 

As workaround, if you find in which cases it happens, you could override BlockBase::blockAccess() to avoid your build() method is called in those cases.