public static function renderAs($data, string $content_type, array $options = []) {
		// clena up output buffer
		\Helper\Ob::cleanAll();
		Application::set('flag.global.__content_type', $content_type);
		Application::set('flag.global.__skip_layout', 1);
		header("Content-type: " . $content_type);
		if (!empty($options['output_file_name'])) {
			header('Content-Disposition: attachment; filename=' . $options['output_file_name']);
		}
		$options['extension'] = ($options['extension'] ?? '');
		switch ($content_type . $options['extension']) {
			case 'application/json':
				echo json_encode($data);
				break;
			case 'application/xml':
				if (is_array($data)) {
					echo array2xml($data);
				} else {
					echo $data;
				}
				break;
			case 'text/html':
				\Helper\Ob::start();
				require(Application::get(['application', 'path_full']) . 'Layout/blank.html');
				echo str_replace([
					'<!-- [numbers: document title] -->',
					'<!-- [numbers: document body] -->'
				], [
					\Layout::renderDocumentTitle(),
					$data
				], \Helper\Ob::clean());
				break;
			case 'text/htmlemail':
				\Helper\Ob::start();
				require(Application::get(['application', 'path_full']) . 'Layout/' . \Application::get('application.layout.email') . '.html');
				echo str_replace([
					'<!-- [numbers: document title] -->',
					'<!-- [numbers: document body] -->'
				], [
					'<title>' . ($options['title'] ?? '') . '</title>',
					$data
				], \Helper\Ob::clean());
				break;
			case 'text/htmlplain':
			default:
				echo $data;
		}
		exit;
	}