create account

[Drupal 8] How to create blocks that present information from a custom settings form. by maple-thunder

View this thread on: hive.blogpeakd.comecency.com
· @maple-thunder ·
$0.04
[Drupal 8] How to create blocks that present information from a custom settings form.
## What Will I Learn ?

- You will learn how to create a custom configuration form.
- You will learn how to read information from a settings file and display it in a block.
- You will learn how to create and place custom blocks.

## Requirements

- A Drupal 8 site, I will be using a fresh install
- A text editor

## Difficulty

- Basic

## Tutorial Contents

To start out I created the directory for the module and a few files for the various settings:
- ms_copyright.info.yml
- ms_copyright.module
- ms_copyright.links.menu.yml
- ms_copyright.routing.yml

![file tree main files.PNG](https://steemitimages.com/DQmaYCPuYEuDjphgzsuLZWXo1tXM1iXscJ4wnrSAbRP2AkB/file%20tree%20main%20files.PNG)
> I called my module *ms_copyright* so any time you see *ms_copyright* you should replace it with your module's name.

- - -

Now I'll explain what these files are for and how I structured them.

#### ms_copyright.info.yml
```yaml
name: Copyright Module
description: Creates blocks to output the copyright and design credit messages
type: module
core: 8.x
```
The .info.yml file tells Drupal what the modules name, description, included files, and other information is. This is mostly used by the "Extend" screen that lists all of the modules installed. 


#### ms_copyright.module
`<?php ?>`.
The .module file won't actually contain any code this time, so we'll open this file and fill it with empty php tags. This is normally where the module logic would go. 


#### ms_copyright.routing.yml
```yaml
ms_copyright.config:
    path: 'admin/config/ms_copyright/config'
    defaults:
        _form: '\Drupal\ms_copyright\Form\CopyrightSettingsForm'
        _title: 'Copyright Settings'
    requirements:
        _permission: 'administer site configuration'
```
The *.routing.yml* file tells Drupal where the configuration form can be found, and who can see it. The *path* sets the URL of the configuration page, while the *_form* tells drupal where in the module to find the code to build the form (This will be coming next). *_permission* tells Drupal who to allow to see the page, it is set so that only users with site configuration access can view it.


#### ms_copyright.links.menu.yml
```yaml
ms_copyright.config:
    title: 'Copyright Settings'
    description: 'Settings for the copyright and design credit blocks.'
    parent: system.admin_config_system
    weight: 10
    route_name: ms_copyright.config
```
The *.links.menu.yml* file defines the menu link for the "Configuration" page in the administer menu (/admin/config). The *title* will be the link to the copyright form in the menu, and the description will be the sub-text underneath. The *parent* sets which group of menu links my module's link gets placed with and the *weight* determines it's place among them. Finally the *route_name* is set to use the route we defined in the *.routing.yml*.  


![Configuration menu.PNG](https://steemitimages.com/DQmakvbYzjWYQyw8V9ADCWkFNJHQ9U5M8V9hV79zPNbZFKF/Configuration%20menu.PNG)
> This is the result of the *.links.menu.yml* file

#### Configuration Form 

Now that the base files are all set up we can start creating the custom form class. Drupal 8 looks for custom blocks in a very specific place, if you don't put the files there it won't find them. This means we have to create a new folder structure, `src/Form/`, to house the form class: `CopyrightSettingsForm.php`. This file will define how the configuration form will be built.

![form folder structure.PNG](https://steemitimages.com/DQmXnzFEjWLK6D8TRjAwXV3ZfjzBdys1AGjex8zny6BygCW/form%20folder%20structure.PNG)

To start out create the CopyrightSettingsForm and have it extend ConfigBaseForm. Because we are extending ConfigBaseForm we need to define a few functions, and those functions will be all that is needed.

```php
<?php

/**
 * @file
 * Contains \Drupal\ms_copyright\Form\CopyrightSettingsForm
 */

namespace Drupal\ms_copyright\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

class CopyrightSettingsForm extends ConfigFormBase
{
    /**
    * {@inheritdoc}
    */
    public function getFormId()
    {
        return 'copyright_settings_form';
    }

    /**
    * {@inheritdoc}
    */
    public function buildForm(array $form, FormStateInterface $form_state)
    {
        // Default text values
        $holder = 'Maple Storm';
        $credit = 'Website design by Maple Thunder';
        $form = parent::buildForm($form, $form_state);
        
        // Grab the configuration file
        $config = $this->config('ms_copyright.settings');
            
        // Set the active variables to display to either
        // the config value, or the default value
        if($config->get('ms_copyright.copyright_holder'))
            $holder = $config->get('ms_copyright.copyright_holder');
        
        if($config->get('ms_copyright.design_credit'))
            $credit = $config->get('ms_copyright.design_credit');


        // Use drupals form api to build the fields of the form.
        $form['copyright_title'] = array(
            '#type' => 'label',
            '#value' => '<h2>Copyright Holder</h2>',
        );

        $form['copyright_holder'] = array(
            '#type' => 'textfield',
            '#value' => $holder,
        );

        $form['design_credit_title'] = array(
            '#type' => 'label',
            '#value' => '<h2>Design Credit</h2>',
        );

        $form['design_credit'] = array(
            '#type' => 'textarea',
            '#value' => $credit,
        );

        return $form;
    }
  
     /**
     * {@inheritdoc}
     */
    public function submitForm(array &$form, FormStateInterface $form_state)
    {
        // Grab the config file
        $config = $this->config('ms_copyright.settings');
        // Save the values in the fields to the config file
        $config->set('ms_copyright.copyright_holder', $form_state->getValue('copyright_holder'));
        $config->set('ms_copyright.design_credit', $form_state->getValue('design_credit'));
        // Save the config file
        $config->save();

        return parent::submitForm($form, $form_state);
    }

    /**
    * {@inheritdoc}
    */
    public function getEditableConfigNames()
    {
        return [
            'ms_copyright.settings',
        ];
    }
}
```
> Entire CopyrightSettingForm.php class

Ok, I know that was a lot of code to just throw out there so I'll go over it a bit. The *getFormId* and *getEditableConfigNames* functions are used to return the unique ID of the form and return the editable config file's name respectively.

The *buildForm* function is what handles the layout of the form, and uses the form api to do it. I wanted to have a default value available so that if there is nothing found in the config file it will still have something to display. So I set a couple default strings, checked to see if the config had values for the fields, and if it didn't I used the default strings.

The *submitForm* function fires when the submit button on the form is pressed. In this function I save the values from the form fields into the config file and run the code the base class has in it's *submitForm* function with `return parent::submitForm($form, $form_state);`

- - -

### Time for the displays

In each of these classes there only needs to be a `build()` function. This function is where I will put all of the code to generate the block display. They will both extend the BlockBase class so I have to include a reference to the class with a *use* statement at the top of each.

#### CopyrightBlock.php
```php
<?php

namespace Drupal\ms_copyright\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
* Provides a 'Copyright' Block.
*
* @Block(
*   id = "ms_copyright_block",
*   admin_label = @Translation("Copyright block"),
*   category = @Translation("Copyright"),
* )
*/
class CopyrightBlock extends BlockBase
{

  /**
   * {@inheritdoc}
   */
  public function build()
  {
    // Set the correct config reference
    $config = \Drupal::config('ms_copyright.settings');
    
      // Grab necessary vars
      $year = date('Y');
      $copyright_symbol = '&#169;&nbsp;';
      $company_name = $config->get('ms_copyright.copyright_holder');

      // Build block markup
      $block_content = '';
      $block_content .= '<div class="col-xs-12 col-sm-6">';
          $block_content .= $copyright_symbol . $year . ' ' . $company_name;
      $block_content .= '</div>';

      $block = array(
          '#markup' => $block_content,
      );

    return $block;
  }

}
```
For the copyright block I save the current year using `date('Y')`, a reference to the copyright symbol with a space after it, and the copyright holder text from the configuration file. Once I have all of these set to variables for easier use I start to build my markup.

When I'm manually building html markup in php like this I like to format it as shown, line by line and indenting in the html style. It's unnecessary, I could have put it all in a single string on one line but I find the format I use to be easier to read and debug.

#### DesignCreditBlock.php
```php
<?php

namespace Drupal\ms_copyright\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
* Provides a 'Design Credit' Block.
*
* @Block(
*   id = "rs_design_credit_block",
*   admin_label = @Translation("Design Credit block"),
*   category = @Translation("Red Sky"),
* )
*/
class DesignCreditBlock extends BlockBase
{
  /**
   * {@inheritdoc}
   */
  public function build()
  {
    // Set the correct config reference
    $config = \Drupal::config('ms_copyright.settings');
    
    $credit = $config->get('ms_copyright.design_credit');

      // Build block markup
      $block_content = '';
      $block_content .= '<div class="col-xs-12 col-sm-6">';
          $block_content .= $credit;
      $block_content .= '</div>';

      $block = array(
          '#markup' => $block_content,
      );

    return $block;
  }

}
```

The design credit block is very similar to the copyright block, the only difference being which variable in the configuration file gets referenced.

- - -

### Placement

Now it's time to get those block displaying on a page. Find your way to the Block Layout page (/admin/structure/block), and scroll to the region you want to place the block in. I'll be using the *Footer Fifth* region. Click on the "Place Block" button next to the region name, then find the block you want to add and click the *Place block* button.

In the configuration modal for the block uncheck the *Display title* option so the titles will be hidden. Some blocks may want to use this feature, but I only want the text that was entered into the configuration file to display. 

![configure block.PNG](https://steemitimages.com/DQmbj5Vca2KgxzrZUHDxAy5DN7mbmfrzBmcgMTGQH8cn9zM/configure%20block.PNG)
> I almost always hide the block titles.

After doing this for both blocks, I made sure they were ordered how I wanted them. Copyright block, then display credit block.

![block layout.PNG](https://steemitimages.com/DQmURVBJDbr1JpkJxxWkacgv8F1tWhGpx8ZT44isRMs4goi/block%20layout.PNG)
> The order in the list will determine the order they appear in the html.

When you go to the front page you can see the result.

![final product.PNG](https://steemitimages.com/DQmWJoFtK8egyEe9vjcRZQPFRgBeg9umiVzXBG9JzGJ2wW2/final%20product.PNG)
👍  
properties (23)
authormaple-thunder
permlinkdrupal-8-how-to-create-blocks-that-present-information-from-a-custom-settings-form
categoryprogramming
json_metadata{"tags":["programming","drupal","tutorial","utopian-io"],"image":["https://steemitimages.com/DQmaYCPuYEuDjphgzsuLZWXo1tXM1iXscJ4wnrSAbRP2AkB/file%20tree%20main%20files.PNG","https://steemitimages.com/DQmakvbYzjWYQyw8V9ADCWkFNJHQ9U5M8V9hV79zPNbZFKF/Configuration%20menu.PNG","https://steemitimages.com/DQmXnzFEjWLK6D8TRjAwXV3ZfjzBdys1AGjex8zny6BygCW/form%20folder%20structure.PNG","https://steemitimages.com/DQmbj5Vca2KgxzrZUHDxAy5DN7mbmfrzBmcgMTGQH8cn9zM/configure%20block.PNG","https://steemitimages.com/DQmURVBJDbr1JpkJxxWkacgv8F1tWhGpx8ZT44isRMs4goi/block%20layout.PNG","https://steemitimages.com/DQmWJoFtK8egyEe9vjcRZQPFRgBeg9umiVzXBG9JzGJ2wW2/final%20product.PNG"],"app":"steemit/0.1","format":"markdown"}
created2018-01-22 10:36:24
last_update2018-01-22 10:36:24
depth0
children1
last_payout2018-01-29 10:36:24
cashout_time1969-12-31 23:59:59
total_payout_value0.042 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length11,348
author_reputation1,660,905,360,122
root_title"[Drupal 8] How to create blocks that present information from a custom settings form."
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id31,349,212
net_rshares3,874,296,915
author_curate_reward""
vote details (1)
@munazza ·
$0.04
I hate programming.I got D grade in my programming course but love to see your devotion.I think you love programing and thanks for sharing knowledge with your steem friends :)
👍  
properties (23)
authormunazza
permlinkre-maple-thunder-drupal-8-how-to-create-blocks-that-present-information-from-a-custom-settings-form-20180122t103934839z
categoryprogramming
json_metadata{"tags":["programming"],"app":"steemit/0.1"}
created2018-01-22 10:39:36
last_update2018-01-22 10:39:36
depth1
children0
last_payout2018-01-29 10:39:36
cashout_time1969-12-31 23:59:59
total_payout_value0.036 HBD
curator_payout_value0.006 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length175
author_reputation2,006,794,128,604
root_title"[Drupal 8] How to create blocks that present information from a custom settings form."
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id31,349,879
net_rshares3,758,068,008
author_curate_reward""
vote details (1)