text(trim(file_get_contents($path))); } public static function exists($template): bool { return is_readable(static::getFullPath($template)); } protected static function isMarkdown($nameOrPath): bool { return strlen($nameOrPath) > 3 && substr($nameOrPath, -3) == '.md'; } protected static function getFullPath($template): string { if ($template && $template[0] == '/') { return $template; } if (static::isMarkdown($template)) { return ContentActions::CONTENT_DIR . '/' . $template; } return ROOT_DIR . '/view/template/' . $template . '.php'; } public static function imagePath($image): string { return '/img/' . $image; } public static function parseMarkdown($template): array { $path = static::getFullPath($template); list($ignored, $frontMatter, $markdown) = explode('---', file_get_contents($path), 3); $metadata = Spyc::YAMLLoadString(trim($frontMatter)); $html = ParsedownExtra::instance()->text(trim($markdown)); return [$metadata, $html]; } public static function compileCss() { $scssCompiler = new \Leafo\ScssPhp\Compiler(); $scssCompiler->setImportPaths([self::SCSS_DIR]); $compress = true; if ($compress) { $scssCompiler->setFormatter('Leafo\ScssPhp\Formatter\Crunched'); } else { $scssCompiler->setFormatter('Leafo\ScssPhp\Formatter\Expanded'); $scssCompiler->setLineNumberStyle(Leafo\ScssPhp\Compiler::LINE_COMMENTS); } $all_css = $scssCompiler->compile(file_get_contents(self::SCSS_DIR . '/all.scss')); file_put_contents(self::CSS_DIR . '/all.css', $all_css); $youtube_css = $scssCompiler->compile(file_get_contents(self::SCSS_DIR . '/youtube.scss')); file_put_contents(self::CSS_DIR . '/youtube.css', $youtube_css); } public static function gzipAssets() { foreach ([self::CSS_DIR => 'css', self::JS_DIR => 'js'] as $dir => $ext) { foreach (glob("$dir/*.$ext") as $file) { Gzip::compressFile($file); } } } protected static function interpolateTokens($html): string { return preg_replace_callback('/{{[\w\.]+}}/is', function ($m) { return i18n::translate(trim($m[0], '}{')); }, $html); } protected static function escapeOnce($value): string { return preg_replace('/&([a-z]+|(#\d+)|(#x[\da-f]+));/i', '&$1;', htmlspecialchars((string)$value, ENT_QUOTES, 'utf-8')); } protected static function attributesToHtml($attributes): string { return implode('', array_map(function ($k, $v) { return $v === true ? " $k" : ($v === false || $v === null || ($v === '' && $k != 'value') ? '' : sprintf(' %s="%s"', $k, static::escapeOnce($v))); }, array_keys($attributes), array_values($attributes))); } public static function renderTag($tag, $attributes = []): string { return $tag ? sprintf('<%s%s />', $tag, static::attributesToHtml($attributes)) : ''; } public static function renderContentTag($tag, $content = null, $attributes = []): string { return $tag ? sprintf('<%s%s>%s', $tag, static::attributesToHtml($attributes), $content, $tag) : ''; } public static function renderJson($data): array { Response::setHeader(Response::HEADER_CONTENT_TYPE, 'application/json'); return ['internal/json', ['json' => $data, '_no_layout' => true]]; } }