0

I am trying to write a custom block module in Drupal 8 that will allow me to place this block into my pages using the block layout screen.

I'm very new to Drupal, so this is very much a "hello world" project (initially) to figure out how this works. To this end, I have been following Youtube video instructions as well as reading through whatever documentation I can find on Internet and also a couple of books, but to no avail [yet].

What I have done is creating a walker directory in the modules folder, where I have created the Walker.info.yml file, whose content is the following.

name: Walker
description: A filewalker
core: 8.x
package: Custom
type: module

In the same directory, I have created the Walker.module file.

/**
 * @file
 * Code for the walker module.
 */

I have then created the module/walker/src/Plugin/Block/ directory and the WalkerBlock.php file with the following content.

/**
 * @file
 * Code for the walker block.
 */

namespace Drupal\walker\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides a walker block
 * 
 * @Block(
 *   id = "walker",
 *   admin_label = @Translation("The walker block"),
 *   category = @Translation("Blocks")
 * )
 */

class WalkerBlock extends BlockBase {
  public function build() {
    return array('#markup' => 'Walker block');
  }
}

If I run the command "find . -type f | grep Walker" from my root Drupal directory, I get the following output.

./modules/Walker/Walker.module
./modules/Walker/src/Plugin/Block/WalkerBlock.php
./modules/Walker/Walker.info.yml

Yet, though the documentation and videos I have read suggest that this should be all I require, the Walker block does not appear in the block layout screen as an option that I can place in one of the block regions.

Can anyone see what I'm doing wrong?

I cleared the cache from /admin/config/development/performance.

  • 1
    Ok I'll help but you do know there is a WAY WAY quicker way for quick code like this look in to drupalconsole.com (gives you a command line tool to generate boiler plate code). – Taggart Jensen Feb 4 '18 at 23:04
  • Welcome to Drupal Answers! First you say you created the module/walker/src/Plugin/Block/ directory (module, without a s), then you show the content of the modules directory. Are you sure you edited the right file, and you installed the module? – kiamlaluno Feb 5 '18 at 7:47
  • If you have Drush 9 installed creating such a module is as simple as typing drush generate module in your terminal. – ya.teck Feb 5 '18 at 13:22
0

Ok can you go to drupal8/admin/modules

and see :

enter image description here

Your:

  • walker.info.yml is correct
  • your Walker.module id fine (however i would use (walker as the dir and walker.module aka non caps)
  • your block looks fine

Thinking Rename all to ./modules/walker/walker.module ./modules/walker/src/Plugin/Block/WalkerBlock.php ./modules/walker/walker.info.yml

as could be Name space issue as "Drupal\walker\Plugin\Block" vs "Drupal\Walker\Plugin\Block" ?

but really every thing looks fine When you install the module you should be able to place the block in admin/structure/block

  • Thanks heaps for your help. I didn't know about the "install" thing, so that was one thing that needed doing. Certainly when I went to the drupal8/admin/modules folder it offered my walker module as an installable component, so thanks heaps for that tip. I still haven't been able to get the module to appear in the list of availalble modules in the block screen - I was fiddling around with it yesterday - was wanting to wait until I'd tried everything before getting back to you. I'm still working this through. Just wanted to acknolwedge and thank you for your help. More comments soon.... – David Buddrige Feb 6 '18 at 2:36
  • So when you click add block it Doesen't show ? – Taggart Jensen Feb 6 '18 at 5:16
  • Thanks - I don't know what I've done to my drupal installation - long story short, I wound up creating a brand new drupal install and then creating a module with the three files already mentioned. I then installed it using the drupal8/admin/modules page and bingo - the module appeared in my list of available blocks. – David Buddrige Feb 6 '18 at 6:36
  • I have no idea why it didn't work on my first site. One thing that might have affected it is that originally the site was expanded under the user "root". The second time I installed it, I changed the owner of all the files under drupal (under /var/www/html/drupal-test/* ) to my own username and changed the group of all the files to www-data. This may have been the issue that messed up the database perhaps? Anyway, thanks so very much for your help. I now have a working "hello world" module. :-) – David Buddrige Feb 6 '18 at 6:36
0

Ok lets review it all.

Your info file looks good.

walker.info.yml: (try to use only lowercasse for the name of your *yml files)

name: Walker
description: A filewalker
core: 8.x
package: Custom
type: module

walker.module:

<?php
/**
 * @file
 * Code for the walker module.
 */

When you use the @file you are making a reference to drupal to a file, in this case you don't need that. In this moment your walker.module should look like:

<?php

Nothing else.

Next you need a controller, that it seems that you don't have it yet, it should be at /modules/walker/src/Controller and the name should be something like WalkerController.php (In this case you are allow to use uppercase), so the walker controller should be this way:

WalkerController.php

<?php
/**
 * @file
 * Contains \Drupal\walker\Controller\WalkerController.
 */
namespace Drupal\walker\Controller;

use Drupal\Core\Controller\ControllerBase;

class WalkerController extends ControllerBase {

  /**
   * Display the markup.
   *
   * @return array
   */

  public function content() {
    return array(
      '#type' => 'markup',
      '#markup' => t('Walker Sample Text Block!'),
    );
  }
}

As you can see here we are using the public function content() to generate the sample text and this is done on the WalkerController.php not in the plugin Block.

Now we'll take a look at the WalkerBlock.php this pluging it's mainly (not only) used to create a form for the administrator user to modify the content that this block will display and it normaly looks like:

WalkerBlock.php

<?php

namespace Drupal\walker\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides a 'Walker Content Block Form' Block.
 *
 * @Block(
 *   id = "walker",
 *   admin_label = @Translation("Walker Content Block Form"),
 *   category = @Translation("Walker Content Block Form"),
 * )
 */

class WalkerBlock extends BlockBase implements BlockPluginInterface {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $name = $config['walker_name'];
   $block = array
    (
  'hello' => array
        (
   '#prefix' => '<p>',
   '#suffix' => '</p>',
         '#markup' => t('hello'),
        ),
  'name' => array
        (
   '#prefix' => '<p>',
   '#suffix' => '</p>',
         '#markup' => t('@name', array('@name' => $name,)),
        )
    );
return $block;  
  }//End build

  /**
  * {@inheritdoc}
  */
  public function blockForm($form, FormStateInterface $form_state) {
    $form = parent::blockForm($form, $form_state);
    $config = $this->getConfiguration();
    $form['walker_name'] = array(
       '#type' => 'textfield',
       '#description' => 'Name to say Hello to',
    );

  }
  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
       $this->configuration['walker_name'] = $form_state->getValue('walker_name');
  }//End blockSubmit

}//End Class

So, in this case the WalkerBlock.php is creating a form to configure the block you set in the region. Don't forget to clean the cache, reload and you should be able to see your block at the layout structure. Go to you block layout click "configure" and you'll see a text field asking for a name, lets say you type "walker" then in the content page will show you "Hello walker".

Youtube tutorials are good but sometime they miss important thinks i recommend you take a look HERE

  • No, a block plugin doesn't need any controller. A controller is for rendering a page that doesn't contain a form. – kiamlaluno Feb 5 '18 at 6:00
  • Exactly, i express my self in the wrong way, because he didn't have a form he needed a controller so the plugin has something to render. He was trying to render content from the block plugin without a form... – Hawk Feb 5 '18 at 6:09
  • The block is rendered from the build() method, not from a controller. In fact, none of the blocks implemented by Drupal core uses a controller. – kiamlaluno Feb 5 '18 at 6:13
  • Yes you are right, in fact the controller, on its own, will not do anything. It needs to be invoked by adding a routing file to our module. So maybe the reason he can se hes block at the block layout is that he was missing /** * Provides a 'Walker Content Block Form' Block. * * @Block( * id = "walker", * admin_label = @Translation("Walker Content Block Form"), * category = @Translation("Walker Content Block Form"), * ) */ – Hawk Feb 5 '18 at 6:19
  • It's not a controller that associates a block to a route. Blocks are associated to any route, as long as there isn't a condition plugin that is telling Drupal not to render a block for a specific route. – kiamlaluno Feb 5 '18 at 6:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.