All files / src/template page.ts

14.29% Statements 4/28
0% Branches 0/2
0% Functions 0/8
14.29% Lines 4/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116  2x 2x 2x                                                                                                                                                                                                                             2x  
import Node from 'type/node';
import Template from 'template';
import getManifest from 'utility/get-manifest';
import AccountMenuTemplate from 'template/partial/account-menu';
 
export interface Breadcrumb {
	readonly label: string;
	readonly url?: string;
}
 
export interface PageTemplateInput {
	readonly account: Node;
}
 
abstract class PageTemplate<T extends PageTemplateInput> extends Template<T> {
	protected getHtml(): string {
		const document_title = this.getDocumentTitle();
		const account_menu_html = this.getAccountMenuHtml();
		const breadcrumbs_html = this.getBreadcrumbsHtml();
		const content_title = this.getContentTitle();
		const content_html = this.getContentHtml();
		const footer_html = this.getFooterHtml();
 
		return `
			<!DOCTYPE html>
			<html>
				<head>
					<title>${document_title}</title>
					<link rel="stylesheet" type="text/css" href="/site.css" media="screen"/>
				</head>
				<body>
					<header>
						${account_menu_html}
						<nav>
							${breadcrumbs_html}
						</nav>
					</header>
 
					<hr />
 
					<main>
						<h1>${content_title}</h1>
						${content_html}
					</main>
 
					<hr />
 
					<footer>
						${footer_html}
					</footer>
				</body>
			</html>
		`;
	}
 
	protected getDocumentTitle(): string {
		return this.getContentTitle();
	}
 
	protected getAccount(): Node {
		const input = this.getInput();
 
		return input.account;
	}
 
	private getAccountMenuHtml(): string {
		const account = this.getAccount();
 
		const template = new AccountMenuTemplate({
			account
		});
 
		return template.render();
	}
 
	private getBreadcrumbsHtml(): string {
		const breadcrumbs = this.getBreadcrumbs();
 
		const serialized_breadcrumbs = breadcrumbs.map((breadcrumb) => {
			return this.getBreadcrumbHtml(breadcrumb);
		});
 
		return serialized_breadcrumbs.join(`
			<em>&gt;</em>
		`);
	}
 
	private getBreadcrumbHtml(breadcrumb: Breadcrumb): string {
		if (breadcrumb.url === undefined) {
			return `<span>${breadcrumb.label}</span>`;
		}
 
		return `
			<a href="${breadcrumb.url}">
				${breadcrumb.label}
			</a>
		`;
	}
 
	private getFooterHtml(): string {
		const manifest = getManifest();
		const project_name = manifest.name;
		const version = manifest.version;
 
		return `
			<span>Running ${project_name} v${version}.</span>
		`;
	}
 
	protected abstract getBreadcrumbs(): Breadcrumb[];
	protected abstract getContentTitle(): string;
	protected abstract getContentHtml(): string;
}
 
export default PageTemplate;