code: public function block($strName)
      {
          $this->arrBlockNames[] = $strName;
  
          // Root template
          if ($this->strParent === null) {
              // Register the block name
              if (!isset($this->arrBlocks[$strName])) {
                  $this->arrBlocks[$strName] = '[[TL_PARENT]]';
              } elseif (is_array($this->arrBlocks[$strName])) {
                  // Combine the contents of the child blocks
                  $callback = function ($current, $parent) {
                      return str_replace('[[TL_PARENT]]', $parent, $current);
                  };
  
                  $this->arrBlocks[$strName] = array_reduce($this->arrBlocks[$strName], $callback, '[[TL_PARENT]]');
              }
  
              // Handle nested blocks
              if ($this->arrBlocks[$strName] != '[[TL_PARENT]]') {
                  // Output everything before the first TL_PARENT tag
                  if (strpos($this->arrBlocks[$strName], '[[TL_PARENT]]') !== false) {
                      list($content) = explode('[[TL_PARENT]]', $this->arrBlocks[$strName], 2);
                      echo $content;
                  } else {
                      // Output the current block and start a new output buffer to remove the following blocks
                      echo $this->arrBlocks[$strName];
                      ob_start();
                  }
              }
          } else {
              // Child template
              // Clean the output buffer
              ob_end_clean();
  
              // Check for nested blocks
              if (count($this->arrBlockNames) > 1) {
                  throw new \Exception('Nested blocks are not allowed in child templates');
              }
  
              // Start a new output buffer
              ob_start();
          }
      }
docs: Start a new block
  
  @param string $strName The block name.
  
  @return void
  
  @throws \Exception If a child templates contains nested blocks.