final public function render_template( $raw_content, $counter = 0, $echo = true ) : string {

		// Load module data from raw ACF layout content.
		$this->load_args_from_layout_content( $raw_content, $counter );

		if ( true !== $this->validate_args() ) {
			return '';
		}

		$template = apply_filters( 'hogan/module/' . $this->name . '/template', $this->template, $this );

		if ( ! file_exists( $template ) || 0 !== validate_file( $template ) ) {
			return '';
		}

		if ( false === $echo ) {
			ob_start();
		}

		// Echo opening wrappers.
		$this->render_opening_template_wrappers( $counter );

		$output_heading_component = true === apply_filters( 'hogan/module/' . $this->name . '/heading/enabled', false ) && ! empty( $this->heading );
		$output_lead_component    = true === apply_filters( 'hogan/module/' . $this->name . '/lead/enabled', false ) && ! empty( $this->lead );
		$wrap_heading_and_lead    = true === apply_filters( 'hogan/module/wrap_heading_and_lead', false, $this ) && ( $output_heading_component || $output_lead_component );

		// Wrap standard fields.
		if ( true === $wrap_heading_and_lead ) {
			printf( '<div class="%s">', esc_attr( hogan_classnames( 'hogan-module-header', 'hogan-module-' . $this->name . '-header' ) ) );
		}

		// Include standard fields.
		if ( true === $output_heading_component ) {
			hogan_component(
				'heading', [
					'title' => $this->heading,
				]
			);
		}

		if ( true === $output_lead_component ) {
			hogan_component(
				'lead', [
					'content' => $this->lead,
				]
			);
		}

		if ( true === $wrap_heading_and_lead ) {
			echo '</div>';
		}

		// Render custom fields before template.
		do_action( 'hogan/module/render_fields_before', $raw_content, $this );

		// Include module template.
		include $template;

		// Render custom fields after template.
		do_action( 'hogan/module/render_fields_after', $raw_content, $this );

		// Echo closing wrappers.
		$this->render_closing_template_wrappers();

		if ( false === $echo ) {
			return ob_get_clean();
		}

		return '';
	}