How to Programmatically Replace the Content in the Custom Block in Drupal 8?
Replacing the content in the custom block is often challenging. In Drupal 8, the best way to replace the content in the custom block programmatically is to use module_preprocess_block alter.
We have created a custom block and now we want to replace the value of the placeholder programmatically. For eg. On http://example.com/, we have created a custom block named “Test Block” for the home page. The body of the custom block contains the following code:
[java]
<div>
<div class="“content”">
<h5><a href="“{{link}}”">Test Block</a></h5> // {{link}} represents the placeholder
</div>
</div>
[/java]
Now we want to replace the value of placeholder ({{link}}) with a node page URL link programmatically. Here’s how to go about it:
Create an alter module by following the below steps:
Step 1- Create a test folder in the modules folder
Step 2- Create “test.info.yml” file that will have entire information about module such as name, type, package, version.
[java]
name: Test Block
description: ‘Module to replace the placeholder.’
package: Custom
type: module
core: 8.x
[/java]
Step 3- Create “test.routing.yml” file and add routing for this module
Step 4- Create “test.module” file which will contain the preprocess alter of the custom block. The custom block contains the placeholder
Step 5- Open the test.module file and add preprocess alter code as shown below:
[java]
use Drupal\Core\Block\BlockBase;
use Drupal\node\Entity\Node;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\field\Entity\FieldConfig;
/**
* function preprocess block for Test block
*/
function test_preprocess_block(&$variables)
{
if (isset($variables[‘content’][‘#block_content’]))
{
$content = $variables[‘content’][‘#block_content’];
if( method_exists($content,’id’) && $content->id() == ‘block_id’)
/*
* Block Id represents id of coressponding block which contains the placeholder.
*/
{
$body = $variables[‘content’][‘body’][0][‘#text’];
/*
* now you need to replace with placeholder by finding the dynamic link
*/
$query = \Drupal::entityQuery(‘node’);
$query->range(0, 1);
$result = $query->execute();
$nids = array_values($result);
if (isset($nids[0]))
{
$node_load = Node::load($nids[0]);
$options = array(‘absolute’=>TRUE);
$url = Url::fromRoute(‘entity.node.canonical’, [ ‘node’=>$nids[0] ], $options);
$Url = $url->toString();
$body=str_replace(‘{{link}}’,$Url,$body);
$variables[‘content’][‘body’][0][‘#text’] = $body;
}
}
}
}
[/java]
The Block Id and the placeholder are highlighted in the following image:
We hope you will able to now replace the content in your custom block easily following the above steps. In case if you have more queries about Drupal 8 custom blocks, feel free to share them in the comments below.
Thanks for useful trickes, I was searching for quite time but finally I was able to change content base on my requirement on the fly. By the way my question is can’t we do same with how to identify particular block using hook_block_alter which i try to used before this but it didn’t work.
Nice & usefull blog