In the previous article we showed how to display the "Hello World" text on your own page. In this article we will show you how to display it in the new block.

1. Add a new PHP class block.

Create this file:

app/code/<VendorName>/<ModuleName>/Block/SomeName.php

and add the following code to it:

<?php
namespace VendorName\ModuleName\Block;
class SomeName extends \Magento\Framework\View\Element\Template
{
    public function getWelcomeText()
    {
        return 'Hello World';
    }
}

where, 

SomeName is a random name in CamelCase format.
\Magento\Framework\View\Element\Template — a class from which you inherit your own block that interacts with the template.
getWelcomeText — a public method we created to return the text "Hello World". You can create a name for it yourself.

2. Add a template file (template .phtml file)

Create this file:

app/code/<VendorName>/<ModuleName>/view/frontend/templates/some-name.phtml

and add the following code there:

<h1><?php echo $block->escapeHtml($block->getWelcomeText()) ?></h1>

For security reasons, skip the text output via the escapeHtml method. This will save the site from HTML injections.

3. Combine the PHP class block and the template file in a layout file.

Create this file:

app/code/<VendorName>/<ModuleName>/view/frontend/layout/<rute_id>_<controller_name>_<action_name>.xml

and add the following code to it:

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="VendorName\ModuleName\Block\SomeName" name="some.block.name" template="VendorName_ModuleName::some-name.phtml" />
        </referenceContainer>
    </body>
</page>

where, 

<rute_id>_<controller_name>_<action_name> — the layout file name, should only be in lower case and contain the router id, controller and action names.

layout — an attribute that defines the type of page layout. The following types are available by default: 1column, 2columns-left, 2columns-right, 3columns, empty. Experiment with them — set different types of layouts and compare them.
content — the name of the container where the block will be placed.

Remember that after changing and saving the layout file, you should clear the Layouts Cache, if it is enabled. Run the CLI command:

php bin/magento cache:clean layout

4. Call the download and rendering of the layout in the controller.

Edit this file:

app/code/<VendorName>/<ModuleName>/Controller/<ControllerName>/<ActionName>.php 

put the following code in the execute method:

$this->_view->loadLayout();
$this->_view->renderLayout();

This is how it should look like:

<?php
namespace VendorName\ModuleName\Controller\ControllerName;
class ActionName extends \Magento\Framework\App\Action\Action
{
    public function execute()
    { $this->_view->loadLayout();
       $this->_view->renderLayout();     }
}

5. Visit the edited page.

Follow this link:
http://your-magento-store.com/path/сontrollerName/actionName/

You will see this page:

Hello Word

In the examples, we will create the Magefan_Faq module for Frequently Asked Question (FAQ). The resulting structure of the module will look like this:

├── app
│   └── code
│       └── Magefan
│          └──
Faq

│              ├──
Block
│              │    └──Index.php
│              │

│              ├── etc

│              │   ├──
module.xml
│              │   └──frontend
│              │      └── routes.xm
│              │
│              ├──
registration.php
│              ├── Controller
│              │   └── Index  // controller_name
│              │       └── Index.php // action_name
│              │
│              └──
view
│                 └── frontend
│                     ├── layout
│                     │   └── magefan_faq_index_index.xml
│                     └── templates
│                        └── index.phtml

You can view the modified Magefan_Faq module files on GitHub.