WordPress Widget vs Drupal 8 Block

Both WordPress and Drupal have long had the ability to place arbitrary content throughout your site. WordPress calls them Widgets, while Drupal has named them Blocks. Beyond the name they essentially provide the same functionality, but previous to Drupal 8, blocks have lacked the ability to be placed on a page more than once.

Not to go into a deep Drupal history lesson here or anything, but TL;DR, Drupal blocks in the past have been: 1 API implementation = 1 block. If you created a block in code, that block could be used exactly once in any given block placement interface. *

As a long time widget/block fan and WordPress/Drupal developer, I was naturally very excited when Drupal 8 adopted an instance approach to blocks that finally matches the flexibility of WordPress’s implementation.

Let’s take a look at how similar they are now

WordPress Widget Example

[pastacode lang=”php” manual=”%3C%3Fphp%0Aclass%20ExampleWidget%20extends%20WP_Widget%20%7B%0A%09%2F**%0A%09%20*%20ExampleWidget%20constructor.%0A%09%20*%2F%0A%09function%20__construct()%20%7B%0A%09%09parent%3A%3A__construct(%0A%09%09%2F%2F%20id_base%0A%09%09%09’example_widget_id’%2C%0A%09%09%09%2F%2F%20title%0A%09%09%09__(%20’My%20example%20widget’%20)%2C%0A%09%09%09%2F%2F%20widget%20options%0A%09%09%09array(%0A%09%09%09%09’classname’%20%20%20%3D%3E%20’examplewidget’%2C%0A%09%09%09%09’description’%20%3D%3E%20__(%20’My%20example%20is%20great!’%20)%0A%09%09%09)%0A%09%09)%3B%0A%09%7D%0A%0A%09%2F**%0A%09%20*%20Echo%20the%20widget%20contents%20to%20the%20screen%0A%09%20*%0A%09%20*%20%40param%20array%20%24args%0A%09%20*%20%40param%20array%20%24instance%0A%09%20*%2F%0A%09function%20widget(%20%24args%2C%20%24instance%20)%20%7B%0A%09%09print%20%22Hello%20%7B%24instance%5B’some_text’%5D%7D%22%3B%0A%09%7D%0A%0A%09%2F**%0A%09%20*%20Display%20the%20widget%20form%20to%20the%20screen%0A%09%20*%0A%09%20*%20%40param%20array%20%24instance%0A%09%20*%2F%0A%09function%20form(%20%24instance%20)%20%7B%0A%09%09%24default_values%20%3D%20array(%0A%09%09%09’some_text’%20%3D%3E%20’Jonathan’%2C%0A%09%09)%3B%0A%09%09%24instance%20%3D%20wp_parse_args(%20%24instance%2C%20%24default_values%20)%3B%0A%09%09%3F%3E%0A%20%20%20%20%20%20%20%20%3Clabel%20for%3D%22%3C%3Fphp%20print%20%24this-%3Eget_field_id(%20’some_text’%20)%20%3F%3E%22%3E%3C%3Fphp%20_e(‘Some%20Text’)%20%3F%3E%3C%2Flabel%3E%0A%20%20%20%20%20%20%20%20%3Cinput%20type%3D%22text%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id%3D%22%3C%3Fphp%20print%20%24this-%3Eget_field_id(%20’some_text’%20)%20%3F%3E%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22%3C%3Fphp%20print%20%24this-%3Eget_field_name(%20’some_text’%20)%20%3F%3E%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%3D%22%3C%3Fphp%20print%20esc_html(%20%24instance%5B’some_text’%5D%20)%20%3F%3E%22%20%2F%3E%0A%09%09%3C%3Fphp%0A%09%7D%0A%0A%09%2F**%0A%09%20*%20Sanitize%20a%20new%20instance%20array%20and%20return%20it%0A%09%20*%0A%09%20*%20%40param%20array%20%24new_instance%0A%09%20*%20%40param%20array%20%24old_instance%0A%09%20*%2F%0A%09function%20update(%20%24new_instance%2C%20%24old_instance%20)%20%7B%0A%09%09%24instance%5B’some_text’%5D%20%3D%20sanitize_text_field(%20%24new_instance%5B’some_text’%5D%20)%3B%0A%09%09return%20%24instance%3B%0A%09%7D%0A%7D” message=”example-wordpress-widget.php” highlight=”” provider=”manual”/]

Widget Form

Drupal 8 Block Example

[pastacode lang=”php” manual=”%3C%3Fphp%0Anamespace%20Drupal%5Cexample_block%5CPlugin%5CBlock%3B%0Ause%20Drupal%5CCore%5CBlock%5CBlockBase%3B%0Ause%20Drupal%5CCore%5CBlock%5CBlockPluginInterface%3B%0Ause%20Drupal%5CCore%5CForm%5CFormStateInterface%3B%0A%2F**%0A%20*%20Provide%20a%20simple%20Block%20to%20Drupal.%0A%20*%0A%20*%20%40Block(%0A%20*%20%20%20id%20%3D%20%22example_block%22%2C%0A%20*%20%20%20admin_label%20%3D%20%40Translation(%22My%20example%20block%22)%0A%20*%20)%0A%20*%2F%0Aclass%20ExampleBlock%20extends%20BlockBase%20implements%20BlockPluginInterface%0A%7B%0A%20%20%2F**%0A%20%20%20*%20Return%20the%20block%20contents%0A%20%20%20*%0A%20%20%20*%20%7B%40inheritdoc%7D%0A%20%20%20*%2F%0A%20%20public%20function%20build()%0A%20%20%7B%0A%20%20%20%20%24config%20%3D%20%24this-%3EgetConfiguration()%3B%0A%20%20%20%20return%20%5B%0A%20%20%20%20%20%20’%23markup’%20%3D%3E%20%22Hello%20%7B%24config%5B’some_text’%5D%7D%22%0A%20%20%20%20%5D%3B%0A%20%20%7D%0A%20%20%2F**%0A%20%20%20*%20Return%20a%20Form%20API%20array%0A%20%20%20*%0A%20%20%20*%20%7B%40inheritdoc%7D%0A%20%20%20*%2F%0A%20%20public%20function%20blockForm(%24form%2C%20FormStateInterface%20%24form_state)%0A%20%20%7B%0A%20%20%20%20%24form%20%3D%20parent%3A%3AblockForm(%24form%2C%20%24form_state)%3B%0A%20%20%20%20%24config%20%3D%20%24this-%3EgetConfiguration()%3B%0A%20%20%20%20%24form%5B’some_text’%5D%20%3D%20%5B%0A%20%20%20%20%20%20’%23type’%20%3D%3E%20’textfield’%2C%0A%20%20%20%20%20%20’%23title’%20%3D%3E%20%24this-%3Et(‘Some%20Text’)%2C%0A%20%20%20%20%20%20’%23default_value’%20%3D%3E%20isset(%24config%5B’some_text’%5D)%20%3F%20%24config%5B’some_text’%5D%20%3A%20’Jonathan’%2C%0A%20%20%20%20%5D%3B%0A%20%20%20%20return%20%24form%3B%0A%20%20%7D%0A%20%20%2F**%0A%20%20%20*%20Update%20the%20configuration%20values%20from%20the%20form%20state%0A%20%20%20*%0A%20%20%20*%20%7B%40inheritdoc%7D%0A%20%20%20*%2F%0A%20%20public%20function%20blockSubmit(%24form%2C%20FormStateInterface%20%24form_state)%0A%20%20%7B%0A%20%20%20%20%24this-%3Econfiguration%5B’some_text’%5D%20%3D%20%24form_state-%3EgetValue(‘some_text’)%3B%0A%20%20%7D%0A%7D” message=”example-drupal-block.php” highlight=”” provider=”manual”/]

Block Form

That’s pretty darn similar!

Summary

Both classes now do the same following things, with the remaining differences primarily being class/method signatures or other internal APIs (Drupal).

Similarities

  • Both systems use inheritance to ease the development of a new subtype.
    WordPress widgets extend the WP_Widget class
    Drupal blocks extend BlockBase
  • Both provide a means of overriding the output of the parent class.
    WordPress calls this method widget()
    Drupal calls it build()
  • Both provide a means of overriding the configuration form of the parent class.
    WordPress calls this method form()
    Drupal calls it blockForm()
  • Both provide a means of saving configuration form values.
    WordPress calls it update()
    Drupal calls it blockSubmit()
  • Both save the configuration to the database on their own.

Differences

  • Drupal requires the use of many more internal APIs not specifically related to the Block API.
  • Drupal’s build() method must return a render array.
    WordPress expects the widget to echo its contents.
  • Drupal’s blockForm() method must return a Form API array.
    WordPress expects the widget to echo the form immediately.
  • On submission of the configuration form:
    Drupal needs you to set the new values within the block’s configuration array
    WordPress expects you to return an array with the new values

That’s not so different!

0 Thoughts

Discussion

Leave a Reply

Your email address will not be published. Required fields are marked *