diff --git a/makai.php b/makai.php index 529dd3c..a1b66a3 100644 --- a/makai.php +++ b/makai.php @@ -12,7 +12,7 @@ define('MKI_DIR_LIB', MKI_ROOT . '/lib'); define('MKI_DIR_PUB', MKI_ROOT . '/public'); define('MKI_DIR_PAGES', MKI_ROOT . '/pages'); define('MKI_DIR_CONFIG', MKI_ROOT . '/config'); -define('MKI_DIR_TEMPLATES', MKI_ROOT . '/tpl'); +define('MKI_DIR_TEMPLATES', MKI_ROOT . '/templates'); require_once MKI_ROOT . '/vendor/autoload.php'; diff --git a/public/index.php b/public/index.php index d75d83e..8dd75da 100644 --- a/public/index.php +++ b/public/index.php @@ -52,14 +52,16 @@ $router = new HttpFx; $router->setDefaultErrorHandler(function($response, $request, $code, $text) use ($ctx) { $path = 'errors/' . $code; $tpl = $ctx->getTemplating(); - $response->setContent($tpl->render($tpl->exists($path) ? $path : 'errors/master', [ + $name = is_file(sprintf('%s/errors/%s.twig', MKI_DIR_TEMPLATES, $code)) ? sprintf('errors/%s.twig', $code) : 'errors/master'; + + $response->setContent($tpl->render($name, [ 'http_error_code' => $code, 'http_error_title' => $text, ])); }); -$router->get('/error/:code', function($response, $request, $code) { - return intval($code); +$router->get('/error/:code', function($response, $request, string $code) { + return (int)$code; }); foreach(MKI_REDIRS as $source => $target) @@ -68,7 +70,7 @@ foreach(MKI_REDIRS as $source => $target) }); $router->use('/', function($response) { - $response->setPoweredBy('Makai+Index'); + $response->setPoweredBy('Makai'); }); $router->get('/header-bgs.json', function() use ($ctx) { @@ -123,12 +125,23 @@ $router->get('/', function() use ($ctx) { } } - $db = $ctx->getDatabase(); + $dbConn = $ctx->getDatabase(); + + $projectInfos = (new Projects($dbConn))->getFeatured(); + $langs = new Languages($dbConn); + + $projects = []; + foreach($projectInfos as $projectInfo) + $projects[] = [ + 'info' => $projectInfo, + 'colour' => $projectInfo->hasColour() ? $projectInfo->getColour() : $langs->getProjectColour($projectInfo), + ]; + + $contacts = (new Contacts($dbConn))->getHomePage(); return $ctx->getTemplating()->render('index', [ - 'projects' => (new Projects($db))->getFeatured(), - 'languages' => new Languages($db), - 'contacts' => (new Contacts($db))->getHomePage(), + 'projects' => $projects, + 'contacts' => $contacts, ]); }); @@ -139,8 +152,17 @@ $router->get('/contact', function() use ($ctx) { }); $router->get('/projects', function() use ($ctx) { - $db = $ctx->getDatabase(); - $projects = (new Projects($db))->getAll(); + $dbConn = $ctx->getDatabase(); + $langs = new Languages($dbConn); + $projectInfos = (new Projects($dbConn))->getAll(); + + $projects = []; + foreach($projectInfos as $projectInfo) + $projects[] = [ + 'info' => $projectInfo, + 'langs' => $langs->getByProject($projectInfo), + 'colour' => $projectInfo->hasColour() ? $projectInfo->getColour() : $langs->getProjectColour($projectInfo), + ]; $sections = [ 'projects' => [ @@ -152,12 +174,16 @@ $router->get('/projects', function() use ($ctx) { return $ctx->getTemplating()->render('projects', [ 'sections' => $sections, - 'languages' => new Languages($db), ]); }); $router->get('/ascii', function() use ($ctx) { - return $ctx->getTemplating()->render('ascii'); + $templating = $ctx->getTemplating(); + $templating->addFilter('chr', 'chr'); + $templating->addFilter('decoct', 'decoct'); + $templating->addFilter('dechex', 'dechex'); + + return $templating->render('ascii'); }); $router->get('/rngstr', function($response, $request) { diff --git a/src/ContactInfo.php b/src/ContactInfo.php index d99ac84..10897cf 100644 --- a/src/ContactInfo.php +++ b/src/ContactInfo.php @@ -2,6 +2,8 @@ namespace Makai; use Index\WString; +use Index\Colour\Colour; +use Index\Colour\ColourRGB; class ContactInfo { private string $name; @@ -48,12 +50,12 @@ class ContactInfo { return $this->icon; } - public function getColour(): int { - return $this->colour; + public function getColour(): Colour { + return ColourRGB::fromRawRGB($this->colour); } - public function getColourHex(): string { - return '#' . str_pad(dechex($this->colour), 6, '0', STR_PAD_LEFT); + public function getColourRaw(): int { + return $this->colour; } public function getDisplay(): WString { diff --git a/src/GitInfo.php b/src/GitInfo.php new file mode 100644 index 0000000..c23f2ad --- /dev/null +++ b/src/GitInfo.php @@ -0,0 +1,24 @@ +colour !== null; } - public function getColour(): ?int { + public function getColour(): Colour { + return $this->colour === null ? Colour::none() : ColourRGB::fromRawRGB($this->colour); + } + + public function getColourRaw(): ?int { return $this->colour; } } diff --git a/src/Languages.php b/src/Languages.php index f7ff7b9..89c772e 100644 --- a/src/Languages.php +++ b/src/Languages.php @@ -1,6 +1,8 @@ getProjectColourRaw($project); + if($raw === null) + return Colour::none(); + + return ColourRGB::fromRawRGB($raw); + } + + public function getProjectColourRaw(ProjectInfo $project): ?int { $stmt = $this->conn->prepare(self::QUERY_PROJECT_COLOUR); $stmt->addParameter(1, $project->getId(), DbType::STRING); $stmt->execute(); @@ -40,7 +50,7 @@ class Languages { if(!$result->next()) return null; - return $result->getInteger(0); + return $result->isNull(0) ? null : $result->getInteger(0); } private static function createObject(IDbResult $result): LanguageInfo { diff --git a/src/MakaiContext.php b/src/MakaiContext.php index 2cd4deb..63768bd 100644 --- a/src/MakaiContext.php +++ b/src/MakaiContext.php @@ -1,30 +1,37 @@ db = $db; + public function __construct(IDbConnection $dbConn) { + $this->dbConn = $dbConn; } public function getDatabase(): IDbConnection { - return $this->db; + return $this->dbConn; } - public function getTemplating(): TemplateContext { - if($this->tpl === null) { - $this->tpl = new TemplateContext(MKI_DIR_TEMPLATES); - $this->tpl->setGlobal('makai', $this); - $this->tpl->setGlobal('header_nav', $this->getDefaultNavigation()); - $this->tpl->setGlobal('header_bgs', $this->getDefaultHeaders()); - $this->tpl->setGlobal('footer_quotes', $this->getFooterQuotes()); + public function getTemplating(): SasaeEnvironment { + if($this->templating === null) { + $isDebug = Environment::isDebug(); + + $this->templating = new SasaeEnvironment( + MKI_DIR_TEMPLATES, + cache: $isDebug ? null : ['Makai', GitInfo::hash(true)], + debug: $isDebug, + ); + $this->templating->addGlobal('header_nav', $this->getDefaultNavigation()); + $this->templating->addGlobal('header_bgs', $this->getDefaultHeaders()); + $this->templating->addGlobal('footer_quotes', $this->getFooterQuotes()); } - return $this->tpl; + return $this->templating; } public function getDefaultNavigation(): array { diff --git a/src/ProjectInfo.php b/src/ProjectInfo.php index d1dfa9d..5e24948 100644 --- a/src/ProjectInfo.php +++ b/src/ProjectInfo.php @@ -4,6 +4,8 @@ namespace Makai; use Index\AString; use Index\WString; use Index\DateTime; +use Index\Colour\Colour; +use Index\Colour\ColourRGB; class ProjectInfo { private string $id; @@ -86,7 +88,11 @@ class ProjectInfo { return $this->colour !== null; } - public function getColour(): ?int { + public function getColour(): Colour { + return $this->colour === null ? Colour::none() : ColourRGB::fromRawRGB($this->colour); + } + + public function getColourRaw(): ?int { return $this->colour; } diff --git a/src/Template.php b/src/Template.php deleted file mode 100644 index c4ff11e..0000000 --- a/src/Template.php +++ /dev/null @@ -1,48 +0,0 @@ -vars->setVar($name, $value); - } - public function removeVar(string $name): void { - $this->vars->removeVar($name); - } - - public function render(array $vars = [], ?TemplateSelf $self = null): string { - if(!is_file($this->path)) - throw new \RuntimeException('Template file does not exist: ' . $this->path); - - $self = new TemplateSelf($this->context->getFunctions() + $vars + $this->vars->getVars(), $self); - $self->tplPath = $this->path; - - $self->var = fn(string $name, mixed $default = null) => $this->vars->getVar($name, $default); - $self->setVar = fn(string $name, mixed $value) => $this->vars->setVar($name, $value); - $self->remVar = fn(string $name) => $this->vars->removeVar($name); - - $self->block = fn(string $name, mixed $contents) => $this->context->setBlock($name, new TemplateBlock($self, $contents)); - $self->include = fn(string $name) => $this->context->render($name, [], $self); - - $self->ctx = $this->context; - $self->extends = fn(string $name) => $self->extends = $name; - - ob_start(); - (static function() use ($self) { include $self->tplPath; })(); - $buffer = ob_get_contents(); - ob_end_clean(); - - if(is_string($self->extends)) { - if(!empty($buffer)) - throw new \RuntimeException('You cannot output from templates that extend another.'); - $buffer = $this->context->render($self->extends, [], $self); - } - - return $buffer; - } -} diff --git a/src/TemplateBlock.php b/src/TemplateBlock.php deleted file mode 100644 index 4c2e750..0000000 --- a/src/TemplateBlock.php +++ /dev/null @@ -1,22 +0,0 @@ -body)) { - ob_start(); - ($this->body)($this->self); - $body = ob_get_contents(); - ob_end_clean(); - } else $body = strval($this->body); - - return $body; - } -} diff --git a/src/TemplateContext.php b/src/TemplateContext.php deleted file mode 100644 index e27fb79..0000000 --- a/src/TemplateContext.php +++ /dev/null @@ -1,56 +0,0 @@ -pathFormat = rtrim($path, '\\/') . DIRECTORY_SEPARATOR . '%s' . self::EXT; - $this->vars = new TemplateVars; - $this->defineFunction('global', $this->vars->getVar(...)); - $this->defineFunction('getBlock', $this->getBlock(...)); - $this->defineFunction('x', fn(string $string) => htmlspecialchars($string, ENT_QUOTES, 'utf-8', true)); - } - - public function setGlobal(string $name, mixed $value): void { - $this->vars->setVar($name, $value); - } - public function removeGlobal(string $name): void { - $this->vars->removeVar($name); - } - - public function defineFunction(string $name, Closure|callable $function): void { - $this->functions[$name] = $function; - } - public function getFunctions(): array { - return $this->functions; - } - - public function create(string $path): Template { - return new Template($this, new TemplateVars($this->vars), sprintf($this->pathFormat, $path)); - } - - public function exists(string $path): bool { - return is_file(sprintf($this->pathFormat, $path)); - } - - public function render(string $path, array $vars = [], ?TemplateSelf $self = null): string { - return $this->create($path)->render($vars, $self); - } - - public function getBlock(string $name, mixed $default = ''): string { - return ($this->blocks[$name] ?? new TemplateBlock(new \stdClass, $default))->render(); - } - - public function setBlock(string $name, TemplateBlock $block): void { - $this->blocks[$name] = $block; - } -} diff --git a/src/TemplateSelf.php b/src/TemplateSelf.php deleted file mode 100644 index 23bed2f..0000000 --- a/src/TemplateSelf.php +++ /dev/null @@ -1,32 +0,0 @@ -members += $inherit->members; - } - - public function __get(string $name): mixed { - return $this->members[$name]; - } - - public function __set(string $name, mixed $value): void { - $this->members[$name] = $value; - } - - public function __isset(string $name): bool { - return isset($this->members[$name]); - } - - public function __unset(string $name): void { - unset($this->members[$name]); - } - - public function __call(string $name, array $args): mixed { - return ($this->members[$name])(...$args); - } -} diff --git a/src/TemplateVars.php b/src/TemplateVars.php deleted file mode 100644 index 756bddf..0000000 --- a/src/TemplateVars.php +++ /dev/null @@ -1,32 +0,0 @@ -vars; - if($this->parent !== null) - $vars += $this->parent->getVars(); - return $vars; - } - - public function getVar(string $name, mixed $default = null): mixed { - if(isset($this->vars[$name])) - return $this->vars[$name]; - if($this->parent !== null) - return $this->parent->getVar($name, $default); - return $default; - } - - public function setVar(string $name, mixed $value): void { - $this->vars[$name] = $value; - } - - public function removeVar(string $name): void { - unset($this->vars[$name]); - } -} diff --git a/templates/ascii.twig b/templates/ascii.twig new file mode 100644 index 0000000..6aa69f7 --- /dev/null +++ b/templates/ascii.twig @@ -0,0 +1,257 @@ +{% extends 'master.twig' %} + +{% set header_title = 'flash.moe / ascii table' %} +{% set header_minimal = true %} + +{% set table = [ + ['Null character', 'NUL'], + ['Start of heading', 'SOH'], + ['Start of text', 'STX'], + ['End of text', 'ETX'], + ['End of transmission', 'EOT'], + ['Enquiry', 'ENQ'], + ['Acknowledgement', 'ACK'], + ['Bell', 'BEL'], + ['Backspace', 'BS' ], + ['Horizontal tab', 'HT' ], + ['Line feed', 'LF' ], + ['Vertical tab', 'VT' ], + ['Form feed', 'FF' ], + ['Carriage return', 'CR' ], + ['Shift out/X-On', 'SO' ], + ['Shift in/X-Off', 'SI' ], + ['Delta line escape', 'DLE'], + ['Device control 1 (often XON)', 'DC1'], + ['Device control 2', 'DC2'], + ['Device control 3 (often XOFF)', 'DC3'], + ['Device control 4', 'DC4'], + ['Negative acknowledgement', 'NAK'], + ['Synchronous idle', 'SYN'], + ['End of transmit block', 'ETB'], + ['Cancel', 'CAN'], + ['End of medium', 'EM' ], + ['Substitute', 'SUB'], + ['Escape', 'ESC'], + ['File separator', 'FS' ], + ['Group separator', 'GS' ], + ['Record separator', 'RS' ], + ['Unit separator', 'US' ], + + ['Space'], + ['Excalamation mark'], + ['Double quotes', 'quot'], + ['Hash'], + ['Dollar'], + ['Percent'], + ['Ampersand', 'amp'], + ['Single quote'], + ['Open parenthesis'], + ['Close parenthesis'], + ['Asterisk'], + ['Plus'], + ['Comma'], + ['Hyphen'], + ['Period'], + ['Slash'], + ['Zero'], + ['One'], + ['Two'], + ['Three'], + ['Four'], + ['Five'], + ['Six'], + ['Seven'], + ['Eight'], + ['Nine'], + ['Colon'], + ['Semicolon'], + ['Less than', 'lt'], + ['Equals'], + ['Greater than', 'gt'], + ['Question mark'], + ['At symbol'], + ['Uppercase A'], + ['Uppercase B'], + ['Uppercase C'], + ['Uppercase D'], + ['Uppercase E'], + ['Uppercase F'], + ['Uppercase G'], + ['Uppercase H'], + ['Uppercase I'], + ['Uppercase J'], + ['Uppercase K'], + ['Uppercase L'], + ['Uppercase M'], + ['Uppercase N'], + ['Uppercase O'], + ['Uppercase P'], + ['Uppercase Q'], + ['Uppercase R'], + ['Uppercase S'], + ['Uppercase T'], + ['Uppercase U'], + ['Uppercase V'], + ['Uppercase W'], + ['Uppercase X'], + ['Uppercase Y'], + ['Uppercase Z'], + ['Opening bracket'], + ['Backslash'], + ['Closing bracket'], + ['Caret'], + ['Underscore'], + ['Accent grave'], + ['Lowercase a'], + ['Lowercase b'], + ['Lowercase c'], + ['Lowercase d'], + ['Lowercase e'], + ['Lowercase f'], + ['Lowercase g'], + ['Lowercase h'], + ['Lowercase i'], + ['Lowercase j'], + ['Lowercase k'], + ['Lowercase l'], + ['Lowercase m'], + ['Lowercase n'], + ['Lowercase o'], + ['Lowercase p'], + ['Lowercase q'], + ['Lowercase r'], + ['Lowercase s'], + ['Lowercase t'], + ['Lowercase u'], + ['Lowercase v'], + ['Lowercase w'], + ['Lowercase x'], + ['Lowercase y'], + ['Lowercase z'], + ['Opening curly brace'], + ['Vertical bar'], + ['Closing curly brace'], + ['Tilde'], + + ['Delete', 'DEL'], +] %} + +{% block container %} +
printable
for all printable characters, or control
for all control characters.
+ {{ project.info.summary }}
+ {% endif %} + + {% if project.info.hasDescription %} + {% set lines = project.info.description|split("\n") %} + {% for line in lines %} +{{ line|trim }}
+ {% endfor %} + {% endif %} +printable
for all printable characters, or control
for all control characters.
- =$project->getSummary();?>
- - - trim(); - if($line->isEmpty()) - continue; - ?> -=$line;?>
- - -