<?hh
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/init.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/core/controller/standard-page/init.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/core/myxhp/init.php';
abstract class Recipe extends GetController {
use StandardPage;
abstract protected function getName(): string;
abstract protected function getFilenames(): Vector<string>;
abstract protected function getDocs(): Vector<(string, string)>;
protected function getDescription(): ?string {
return null;
}
final protected function getTitle(): string {
return $this->getName().' - Hack Cookbook';
}
final protected function renderMainColumn(): :xhp {
$main_column =
<x:frag>
<h1>{$this->getName()}</h1>
</x:frag>;
$description = $this->getDescription();
if ($description !== null) {
$main_column->appendChild(<p>{$description}</p>);
}
foreach ($this->getFilenames() as $filename) {
$file =
<div class="file">
<div class="filename">{$filename}</div>
<phpfile filename={$filename}/>
</div>;
$main_column->appendChild($file);
}
$recipe = $this;
if ($recipe instanceof RecipeWithDemo) {
try {
$result = $recipe->getDemoResult();
} catch (Exception $e) {
$result = sprintf(
"Demo threw an %s:\n%s",
get_class($e),
$e->getMessage(),
);
}
$result = explode("\n", trim($result));
$result = array_map($x ==> <x:frag>{$x}<br/></x:frag>, $result);
$demo =
<x:frag>
<div class="demo" id="demo">
<h3>Demo</h3>
{$recipe->getDemoXHP()}
<div class="filename">{$recipe->getDemoFilename()}</div>
<phpfile filename={$recipe->getDemoFilename()}/>
<div class="filename">Output</div>
<div class="demoResult">
{$result}
</div>
</div>
</x:frag>;
$main_column->appendChild($demo);
}
if (!$this->getDocs()->isEmpty()) {
$render_doc_link = function($doc) {
list($name, $link) = $doc;
$link = "http://hhvm.com/manual/en/$link.php";
return <li><a href={$link}>{$name}</a></li>;
};
$main_column->appendChild(
<div class="docs">
<h3>Relevant Official Documentation</h3>
<ul>
{$this->getDocs()->map($render_doc_link)->toArray()}
</ul>
</div>
);
}
return $main_column;
}
}