From 9dd2345ecfff4f7d65ec106a8aee8d866c972585 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Thu, 1 Feb 2024 00:18:42 +0300 Subject: use .phps extension for skin files --- README.md | 2 +- engine/skin.php | 2 +- skin/admin.phps | 346 +++++++++++++++++++++++++++++++++++++++++++++++++ skin/admin.skin.php | 346 ------------------------------------------------- skin/base.phps | 324 +++++++++++++++++++++++++++++++++++++++++++++ skin/base.skin.php | 324 --------------------------------------------- skin/error.phps | 23 ++++ skin/error.skin.php | 23 ---- skin/main.phps | 241 ++++++++++++++++++++++++++++++++++ skin/main.skin.php | 241 ---------------------------------- skin/markdown.phps | 43 ++++++ skin/markdown.skin.php | 43 ------ skin/rss.phps | 29 +++++ skin/rss.skin.php | 29 ----- 14 files changed, 1008 insertions(+), 1008 deletions(-) create mode 100644 skin/admin.phps delete mode 100644 skin/admin.skin.php create mode 100644 skin/base.phps delete mode 100644 skin/base.skin.php create mode 100644 skin/error.phps delete mode 100644 skin/error.skin.php create mode 100644 skin/main.phps delete mode 100644 skin/main.skin.php create mode 100644 skin/markdown.phps delete mode 100644 skin/markdown.skin.php create mode 100644 skin/rss.phps delete mode 100644 skin/rss.skin.php diff --git a/README.md b/README.md index 2a80337..6898a63 100644 --- a/README.md +++ b/README.md @@ -68,4 +68,4 @@ I'm willing to pay $50 to $500 in crypto (depending on severity) for every disco ## License -BSD-2-Clause \ No newline at end of file +BSD-2-Clause diff --git a/engine/skin.php b/engine/skin.php index 6150668..a589370 100644 --- a/engine/skin.php +++ b/engine/skin.php @@ -96,7 +96,7 @@ class SkinContext { function __construct(string $namespace) { $this->ns = $namespace; - require_once APP_ROOT.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).'.skin.php'; + require_once APP_ROOT.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).'.phps'; } function __call($name, array $arguments) { diff --git a/skin/admin.phps b/skin/admin.phps new file mode 100644 index 0000000..d2fc148 --- /dev/null +++ b/skin/admin.phps @@ -0,0 +1,346 @@ + + +
+
{$ctx->lang('as_form_password')}:
+
+ +
+
+
+
+
+ +
+
+ +HTML; + +$js = << + + Sign out + +HTML; +} + + +// uploads page +// ------------ + +function uploads($ctx, $uploads, $error) { +return <<if_true($error, $ctx->formError, $error)} + +
+
+ + +
+
{$ctx->lang('blog_upload_form_file')}:
+
+ +
+
+ +
+
{$ctx->lang('blog_upload_form_custom_name')}:
+
+ +
+
+ +
+
{$ctx->lang('blog_upload_form_note')}:
+
+ +
+
+ +
+
+
+ +
+
+
+
+ +
+ {$ctx->for_each($uploads, fn($u) => $ctx->uploadsItem( + id: $u->id, + name: $u->name, + direct_url: $u->getDirectUrl(), + note: $u->note, + addslashes_note: $u->note, + markdown: $u->getMarkdown(), + size: $u->getSize(), + ))} +
+HTML; +} + +function uploadsItem($ctx, $id, $direct_url, $note, $addslashes_note, $markdown, $name, $size) { +return << + + + {$ctx->if_true($note, '
'.$note.'
')} +
{$size}
+ + +HTML; +} + +function postForm($ctx, + string|Stringable $title, + string|Stringable $text, + string|Stringable $short_name, + string|Stringable $tags = '', + bool $is_edit = false, + $error_code = null, + ?bool $saved = null, + ?bool $visible = null, + ?bool $toc = null, + string|Stringable|null $post_url = null, + ?int $post_id = null): array { +$form_url = !$is_edit ? '/write/' : $post_url.'edit/'; + +$html = <<if_true($error_code, fn() => '
'.$ctx->lang('err_blog_'.$error_code).'
')} +{$ctx->if_true($saved, fn() => '
'.$ctx->lang('info_saved').'
')} + + + + + +
+
+ + +
+
{$ctx->lang('blog_write_form_title')}
+
+ +
+
+ +
+
{$ctx->lang('blog_write_form_text')}
+ +
+ +
+ + + + + + + + + +
+
+
{$ctx->lang('blog_write_form_tags')}
+
+ +
+
+
+
+
{$ctx->lang('blog_write_form_options')}
+
+ + +
+
+
+
+
{$ctx->lang('blog_write_form_short_name')}
+
+ +
+
+
+
+
 
+
+ +
+
+
+
+
+
+
+
+
+HTML; + +$js_params = json_encode($is_edit + ? ['edit' => true, 'id' => $post_id] + : (object)[]); +$js = "AdminWriteForm.init({$js_params});"; + +return [$html, $js]; +} + + +function pageForm($ctx, + string|Stringable $title, + string|Stringable $text, + string|Stringable $short_name, + bool $is_edit = false, + $error_code = null, + ?bool $saved = null, + bool $visible = false): array { +$form_url = '/'.$short_name.'/'.($is_edit ? 'edit' : 'create').'/'; +$html = <<if_true($error_code, fn() => '
'.$ctx->lang('err_pages_'.$error_code).'
')} +{$ctx->if_true($saved, fn() => '
'.$ctx->lang('info_saved').'
')} + + + + + +
+
+ + +
+
{$ctx->lang('pages_write_form_title')}
+
+ +
+
+ +
+
{$ctx->lang('pages_write_form_text')}
+ +
+ + {$ctx->if_then_else($is_edit, + fn() => $ctx->pageFormEditOptions($short_name, $visible), + fn() => $ctx->pageFormAddOptions($short_name))} + +
+
+
+
+
+HTML; + +$js_params = json_encode(['pages' => true, 'edit' => $is_edit]); +$js = << + + + + + + + + +
+
+
{$ctx->lang('pages_write_form_short_name')}
+
+ +
+
+
+
+
{$ctx->lang('pages_write_form_options')}
+
+ +
+
+
+ +
+ +HTML; +} + +function pageFormAddOptions($ctx, $short_name) { +return << +
+
+ +
+ + +HTML; +} + +function pageNew($ctx, $short_name) { +return << + + +HTML; + +} + +// misc +function formError($ctx, $error) { +return <<{$ctx->lang('error')}: {$error} +HTML; +} + +function markdownPreview($ctx, $unsafe_html, $title) { +return << + {$ctx->if_true($title, '

'.$title.'

')} +
{$unsafe_html}
+ +HTML; + +} \ No newline at end of file diff --git a/skin/admin.skin.php b/skin/admin.skin.php deleted file mode 100644 index d2fc148..0000000 --- a/skin/admin.skin.php +++ /dev/null @@ -1,346 +0,0 @@ - - -
-
{$ctx->lang('as_form_password')}:
-
- -
-
-
-
-
- -
-
- -HTML; - -$js = << - - Sign out - -HTML; -} - - -// uploads page -// ------------ - -function uploads($ctx, $uploads, $error) { -return <<if_true($error, $ctx->formError, $error)} - -
-
- - -
-
{$ctx->lang('blog_upload_form_file')}:
-
- -
-
- -
-
{$ctx->lang('blog_upload_form_custom_name')}:
-
- -
-
- -
-
{$ctx->lang('blog_upload_form_note')}:
-
- -
-
- -
-
-
- -
-
-
-
- -
- {$ctx->for_each($uploads, fn($u) => $ctx->uploadsItem( - id: $u->id, - name: $u->name, - direct_url: $u->getDirectUrl(), - note: $u->note, - addslashes_note: $u->note, - markdown: $u->getMarkdown(), - size: $u->getSize(), - ))} -
-HTML; -} - -function uploadsItem($ctx, $id, $direct_url, $note, $addslashes_note, $markdown, $name, $size) { -return << - - - {$ctx->if_true($note, '
'.$note.'
')} -
{$size}
- - -HTML; -} - -function postForm($ctx, - string|Stringable $title, - string|Stringable $text, - string|Stringable $short_name, - string|Stringable $tags = '', - bool $is_edit = false, - $error_code = null, - ?bool $saved = null, - ?bool $visible = null, - ?bool $toc = null, - string|Stringable|null $post_url = null, - ?int $post_id = null): array { -$form_url = !$is_edit ? '/write/' : $post_url.'edit/'; - -$html = <<if_true($error_code, fn() => '
'.$ctx->lang('err_blog_'.$error_code).'
')} -{$ctx->if_true($saved, fn() => '
'.$ctx->lang('info_saved').'
')} - - - - - -
-
- - -
-
{$ctx->lang('blog_write_form_title')}
-
- -
-
- -
-
{$ctx->lang('blog_write_form_text')}
- -
- -
- - - - - - - - - -
-
-
{$ctx->lang('blog_write_form_tags')}
-
- -
-
-
-
-
{$ctx->lang('blog_write_form_options')}
-
- - -
-
-
-
-
{$ctx->lang('blog_write_form_short_name')}
-
- -
-
-
-
-
 
-
- -
-
-
-
-
-
-
-
-
-HTML; - -$js_params = json_encode($is_edit - ? ['edit' => true, 'id' => $post_id] - : (object)[]); -$js = "AdminWriteForm.init({$js_params});"; - -return [$html, $js]; -} - - -function pageForm($ctx, - string|Stringable $title, - string|Stringable $text, - string|Stringable $short_name, - bool $is_edit = false, - $error_code = null, - ?bool $saved = null, - bool $visible = false): array { -$form_url = '/'.$short_name.'/'.($is_edit ? 'edit' : 'create').'/'; -$html = <<if_true($error_code, fn() => '
'.$ctx->lang('err_pages_'.$error_code).'
')} -{$ctx->if_true($saved, fn() => '
'.$ctx->lang('info_saved').'
')} - - - - - -
-
- - -
-
{$ctx->lang('pages_write_form_title')}
-
- -
-
- -
-
{$ctx->lang('pages_write_form_text')}
- -
- - {$ctx->if_then_else($is_edit, - fn() => $ctx->pageFormEditOptions($short_name, $visible), - fn() => $ctx->pageFormAddOptions($short_name))} - -
-
-
-
-
-HTML; - -$js_params = json_encode(['pages' => true, 'edit' => $is_edit]); -$js = << - - - - - - - - -
-
-
{$ctx->lang('pages_write_form_short_name')}
-
- -
-
-
-
-
{$ctx->lang('pages_write_form_options')}
-
- -
-
-
- -
- -HTML; -} - -function pageFormAddOptions($ctx, $short_name) { -return << -
-
- -
- - -HTML; -} - -function pageNew($ctx, $short_name) { -return << - - -HTML; - -} - -// misc -function formError($ctx, $error) { -return <<{$ctx->lang('error')}: {$error} -HTML; -} - -function markdownPreview($ctx, $unsafe_html, $title) { -return << - {$ctx->if_true($title, '

'.$title.'

')} -
{$unsafe_html}
- -HTML; - -} \ No newline at end of file diff --git a/skin/base.phps b/skin/base.phps new file mode 100644 index 0000000..d583ffe --- /dev/null +++ b/skin/base.phps @@ -0,0 +1,324 @@ + $config['domain'], + 'devMode' => $config['is_dev'], + 'cookieHost' => $config['cookie_host'], +]); + +$body_class = []; +if ($opts['full_width']) + $body_class[] = 'full-width'; +else if ($opts['wide']) + $body_class[] = 'wide'; +if (!empty($body_class)) + $body_class = implode(' ', $body_class); +else + $body_class = ''; + +return << + + + + + + + {$title} + + {$ctx->renderMeta($meta)} + {$ctx->renderStatic($static, $theme)} + + if_true($body_class, ' class="'.$body_class.'"')}> + {$ctx->renderHeader($theme, renderLogo($ctx, $opts['logo_path_map'], $opts['logo_link_map']))} +
+
{$unsafe_body}
+
+ {$ctx->renderScript($js, $unsafe_lang, $opts['dynlogo_enabled'])} + + + + + + + + +HTML; +} + +function renderScript($ctx, $unsafe_js, $unsafe_lang, $enable_dynlogo) { +global $config; + +$styles = json_encode($ctx->styleNames); +if ($config['is_dev']) + $versions = '{}'; +else { + $versions = []; + foreach ($config['static'] as $name => $v) { + list($type, $bname) = getStaticNameParts($name); + $versions[$type][$bname] = $v; + } + $versions = json_encode($versions); +} + +return << +StaticManager.init({$styles}, {$versions}); +{$ctx->if_true($unsafe_js, '(function(){'.$unsafe_js.'})();')} +{$ctx->if_true($unsafe_lang, 'extend(__lang, '.$unsafe_lang.');')} +{$ctx->if_true($enable_dynlogo, 'DynamicLogo.init();')} +ThemeSwitcher.init(); + +HTML; +} + +function renderMeta($ctx, $meta) { + if (empty($meta)) + return ''; + return implode('', array_map(function(array $item): string { + $s = ' $v) + $s .= ' '.htmlescape($k).'="'.htmlescape($v).'"'; + $s .= '>'; + return $s; + }, $meta)); +} + +function renderStatic($ctx, $static, $theme) { + global $config; + $html = []; + $dark = $theme == 'dark'; + $ctx->styleNames = []; + foreach ($static as $name) { + // javascript + if (str_starts_with($name, 'js/')) + $html[] = jsLink($name); + + // css + else if (str_starts_with($name, 'css/')) { + $html[] = cssLink($name, 'light', $style_name); + $ctx->styleNames[] = $style_name; + + if ($dark) + $html[] = cssLink($name, 'dark', $style_name); + else if (!$config['is_dev']) + $html[] = cssPrefetchLink($style_name.'_dark'); + } + else + logError(__FUNCTION__.': unexpected static entry: '.$name); + } + return implode("\n", $html); +} + +function jsLink(string $name): string { + global $config; + list (, $bname) = getStaticNameParts($name); + if ($config['is_dev']) { + $href = '/js.php?name='.urlencode($bname).'&v='.time(); + } else { + $href = '/dist-js/'.$bname.'.js?'.getStaticVersion($name); + } + return ''; +} + +function cssLink(string $name, string $theme, &$bname = null): string { + global $config; + + list(, $bname) = getStaticNameParts($name); + + if ($config['is_dev']) { + $href = '/sass.php?name='.urlencode($bname).'&theme='.$theme.'&v='.time(); + } else { + $version = getStaticVersion('css/'.$bname.($theme == 'dark' ? '_dark' : '').'.css'); + $href = '/dist-css/'.$bname.($theme == 'dark' ? '_dark' : '').'.css?'.$version; + } + + $id = 'style_'.$bname; + if ($theme == 'dark') + $id .= '_dark'; + + return ''; +} + +function cssPrefetchLink(string $name): string { +$url = '/dist-css/'.$name.'.css?'.getStaticVersion('css/'.$name.'.css'); +return << +HTML; +} + +function getStaticNameParts(string $name): array { + $dname = dirname($name); + $bname = basename($name); + if (($pos = strrpos($bname, '.'))) { + $ext = substr($bname, $pos+1); + $bname = substr($bname, 0, $pos); + } else { + $ext = ''; + } + return [$dname, $bname, $ext]; +} + +function getStaticVersion(string $name): string { + global $config; + if ($config['is_dev']) + return time(); + if (str_starts_with($name, '/')) { + logWarning(__FUNCTION__.': '.$name.' starts with /'); + $name = substr($name, 1); + } + return $config['static'][$name] ?? 'notfound'; +} + +function renderHeader($ctx, $theme, $unsafe_logo_html) { +$items = [ + ['url' => 'javascript:void(0)', 'label' => $theme, 'label_id' => 'theme-switcher-label', 'theme_switcher' => true], + ['url' => '/', 'label' => 'blog'], + ['url' => '/projects/', 'label' => 'projects'], + ['url' => 'https://git.ch1p.io/?s=idle', 'label' => 'git'], + ['url' => '/misc/', 'label' => 'misc'], + ['url' => '/contacts/', 'label' => 'contacts'], +]; +if (\is_admin()) + $items[] = ['url' => '/admin/', 'label' => 'admin']; + +// here, items are rendered using for_each, so that there are no gaps (whitespaces) between tags + +return << +
+ +
+ {$ctx->for_each($items, fn($item) => $ctx->renderHeaderItem($item['url'], $item['label'], $item['label_id'] ?? null, $item['theme_switcher'] ?? false))} +
+
+ +HTML; +} + +function renderHeaderItem($ctx, $url, $label, $label_id, $is_theme_switcher) { +return <<if_true($is_theme_switcher, ' onclick="return ThemeSwitcher.next(event)"')}> + + {$ctx->if_true($is_theme_switcher, ''.$ctx->renderMoonIcon().'')} + if_true($label_id, ' id="'.$label_id.'"')}>{$label} + + +HTML; +} + +// TODO rewrite this fcking crap +function renderLogo($ctx, array $path_map = [], array $link_map = []): string { + $uri = request_path(); + + if (!is_admin()) { + $prompt_sign = '$'; + } else { + $prompt_sign = '#'; + } + + if ($uri == '/') { + $html = '/home/'.$ctx->lang('ch1p').' '.$prompt_sign; + } else { + $uri_len = strlen($uri); + + $html = ''; + $close_tags = 0; + + $path_parts = []; + $path_links = []; + + $last_pos = 0; + $cur_path = ''; + while ($last_pos < $uri_len) { + $first = $last_pos === 0; + $end = false; + + $pos = strpos($uri, '/', $last_pos); + if ($pos === false || $pos == $uri_len-1) { + $pos = $uri_len-1; + $end = true; + } + + $part = substr($uri, $last_pos, $pos - $last_pos + 1); + $cur_path .= $part; + + if ($end) { + if (substr($part, -1) == '/') + $part = substr($part, 0, strlen($part)-1); + $cur_path = '/'; + $html .= str_repeat('', $close_tags-1); + $close_tags = 1; + } + + $span_class = 'head-logo-path'; + if ($first) { + $span_class .= ' alwayshover'; + } else if ($end) { + $span_class .= ' neverhover'; + } + + $html .= '${{'.count($path_parts).'}}'; + $path_parts[] = ($first ? '~' : '').$part; + $path_links[] = $cur_path; + + $last_pos = $pos + 1; + $close_tags++; + } + $html .= str_repeat('', $close_tags).' '.$prompt_sign.' cd ~ '.enterIcon().'Enter'; + + for ($i = count($path_parts)-1, $j = 0; $i >= 0; $i--, $j++) { + if (isset($path_map[$j])) { + $tmp = htmlescape(strtrim($path_map[$j], 40, $trimmed)); + if ($trimmed) + $tmp .= '…'; + $tmp_html = ''.$tmp.''; + if ($j > 0) + $tmp_html .= '/'; + $html = str_replace_once('${{'.$i.'}}', $tmp_html, $html); + } else { + $html = str_replace_once('${{'.$i.'}}', $path_parts[$i], $html); + } + + if (isset($link_map[$j])) { + $html = str_replace_once('$[['.$i.']]', $link_map[$j], $html); + } else { + $html = str_replace_once('$[['.$i.']]', $path_links[$i], $html); + } + } + } + + return $html; +} + +function enterIcon() { +return << + + +SVG; +} + +function renderMoonIcon($ctx) { +return << +SVG; +} diff --git a/skin/base.skin.php b/skin/base.skin.php deleted file mode 100644 index d583ffe..0000000 --- a/skin/base.skin.php +++ /dev/null @@ -1,324 +0,0 @@ - $config['domain'], - 'devMode' => $config['is_dev'], - 'cookieHost' => $config['cookie_host'], -]); - -$body_class = []; -if ($opts['full_width']) - $body_class[] = 'full-width'; -else if ($opts['wide']) - $body_class[] = 'wide'; -if (!empty($body_class)) - $body_class = implode(' ', $body_class); -else - $body_class = ''; - -return << - - - - - - - {$title} - - {$ctx->renderMeta($meta)} - {$ctx->renderStatic($static, $theme)} - - if_true($body_class, ' class="'.$body_class.'"')}> - {$ctx->renderHeader($theme, renderLogo($ctx, $opts['logo_path_map'], $opts['logo_link_map']))} -
-
{$unsafe_body}
-
- {$ctx->renderScript($js, $unsafe_lang, $opts['dynlogo_enabled'])} - - - - - - - - -HTML; -} - -function renderScript($ctx, $unsafe_js, $unsafe_lang, $enable_dynlogo) { -global $config; - -$styles = json_encode($ctx->styleNames); -if ($config['is_dev']) - $versions = '{}'; -else { - $versions = []; - foreach ($config['static'] as $name => $v) { - list($type, $bname) = getStaticNameParts($name); - $versions[$type][$bname] = $v; - } - $versions = json_encode($versions); -} - -return << -StaticManager.init({$styles}, {$versions}); -{$ctx->if_true($unsafe_js, '(function(){'.$unsafe_js.'})();')} -{$ctx->if_true($unsafe_lang, 'extend(__lang, '.$unsafe_lang.');')} -{$ctx->if_true($enable_dynlogo, 'DynamicLogo.init();')} -ThemeSwitcher.init(); - -HTML; -} - -function renderMeta($ctx, $meta) { - if (empty($meta)) - return ''; - return implode('', array_map(function(array $item): string { - $s = ' $v) - $s .= ' '.htmlescape($k).'="'.htmlescape($v).'"'; - $s .= '>'; - return $s; - }, $meta)); -} - -function renderStatic($ctx, $static, $theme) { - global $config; - $html = []; - $dark = $theme == 'dark'; - $ctx->styleNames = []; - foreach ($static as $name) { - // javascript - if (str_starts_with($name, 'js/')) - $html[] = jsLink($name); - - // css - else if (str_starts_with($name, 'css/')) { - $html[] = cssLink($name, 'light', $style_name); - $ctx->styleNames[] = $style_name; - - if ($dark) - $html[] = cssLink($name, 'dark', $style_name); - else if (!$config['is_dev']) - $html[] = cssPrefetchLink($style_name.'_dark'); - } - else - logError(__FUNCTION__.': unexpected static entry: '.$name); - } - return implode("\n", $html); -} - -function jsLink(string $name): string { - global $config; - list (, $bname) = getStaticNameParts($name); - if ($config['is_dev']) { - $href = '/js.php?name='.urlencode($bname).'&v='.time(); - } else { - $href = '/dist-js/'.$bname.'.js?'.getStaticVersion($name); - } - return ''; -} - -function cssLink(string $name, string $theme, &$bname = null): string { - global $config; - - list(, $bname) = getStaticNameParts($name); - - if ($config['is_dev']) { - $href = '/sass.php?name='.urlencode($bname).'&theme='.$theme.'&v='.time(); - } else { - $version = getStaticVersion('css/'.$bname.($theme == 'dark' ? '_dark' : '').'.css'); - $href = '/dist-css/'.$bname.($theme == 'dark' ? '_dark' : '').'.css?'.$version; - } - - $id = 'style_'.$bname; - if ($theme == 'dark') - $id .= '_dark'; - - return ''; -} - -function cssPrefetchLink(string $name): string { -$url = '/dist-css/'.$name.'.css?'.getStaticVersion('css/'.$name.'.css'); -return << -HTML; -} - -function getStaticNameParts(string $name): array { - $dname = dirname($name); - $bname = basename($name); - if (($pos = strrpos($bname, '.'))) { - $ext = substr($bname, $pos+1); - $bname = substr($bname, 0, $pos); - } else { - $ext = ''; - } - return [$dname, $bname, $ext]; -} - -function getStaticVersion(string $name): string { - global $config; - if ($config['is_dev']) - return time(); - if (str_starts_with($name, '/')) { - logWarning(__FUNCTION__.': '.$name.' starts with /'); - $name = substr($name, 1); - } - return $config['static'][$name] ?? 'notfound'; -} - -function renderHeader($ctx, $theme, $unsafe_logo_html) { -$items = [ - ['url' => 'javascript:void(0)', 'label' => $theme, 'label_id' => 'theme-switcher-label', 'theme_switcher' => true], - ['url' => '/', 'label' => 'blog'], - ['url' => '/projects/', 'label' => 'projects'], - ['url' => 'https://git.ch1p.io/?s=idle', 'label' => 'git'], - ['url' => '/misc/', 'label' => 'misc'], - ['url' => '/contacts/', 'label' => 'contacts'], -]; -if (\is_admin()) - $items[] = ['url' => '/admin/', 'label' => 'admin']; - -// here, items are rendered using for_each, so that there are no gaps (whitespaces) between tags - -return << -
- -
- {$ctx->for_each($items, fn($item) => $ctx->renderHeaderItem($item['url'], $item['label'], $item['label_id'] ?? null, $item['theme_switcher'] ?? false))} -
-
- -HTML; -} - -function renderHeaderItem($ctx, $url, $label, $label_id, $is_theme_switcher) { -return <<if_true($is_theme_switcher, ' onclick="return ThemeSwitcher.next(event)"')}> - - {$ctx->if_true($is_theme_switcher, ''.$ctx->renderMoonIcon().'')} - if_true($label_id, ' id="'.$label_id.'"')}>{$label} - - -HTML; -} - -// TODO rewrite this fcking crap -function renderLogo($ctx, array $path_map = [], array $link_map = []): string { - $uri = request_path(); - - if (!is_admin()) { - $prompt_sign = '$'; - } else { - $prompt_sign = '#'; - } - - if ($uri == '/') { - $html = '/home/'.$ctx->lang('ch1p').' '.$prompt_sign; - } else { - $uri_len = strlen($uri); - - $html = ''; - $close_tags = 0; - - $path_parts = []; - $path_links = []; - - $last_pos = 0; - $cur_path = ''; - while ($last_pos < $uri_len) { - $first = $last_pos === 0; - $end = false; - - $pos = strpos($uri, '/', $last_pos); - if ($pos === false || $pos == $uri_len-1) { - $pos = $uri_len-1; - $end = true; - } - - $part = substr($uri, $last_pos, $pos - $last_pos + 1); - $cur_path .= $part; - - if ($end) { - if (substr($part, -1) == '/') - $part = substr($part, 0, strlen($part)-1); - $cur_path = '/'; - $html .= str_repeat('', $close_tags-1); - $close_tags = 1; - } - - $span_class = 'head-logo-path'; - if ($first) { - $span_class .= ' alwayshover'; - } else if ($end) { - $span_class .= ' neverhover'; - } - - $html .= '${{'.count($path_parts).'}}'; - $path_parts[] = ($first ? '~' : '').$part; - $path_links[] = $cur_path; - - $last_pos = $pos + 1; - $close_tags++; - } - $html .= str_repeat('', $close_tags).' '.$prompt_sign.' cd ~ '.enterIcon().'Enter'; - - for ($i = count($path_parts)-1, $j = 0; $i >= 0; $i--, $j++) { - if (isset($path_map[$j])) { - $tmp = htmlescape(strtrim($path_map[$j], 40, $trimmed)); - if ($trimmed) - $tmp .= '…'; - $tmp_html = ''.$tmp.''; - if ($j > 0) - $tmp_html .= '/'; - $html = str_replace_once('${{'.$i.'}}', $tmp_html, $html); - } else { - $html = str_replace_once('${{'.$i.'}}', $path_parts[$i], $html); - } - - if (isset($link_map[$j])) { - $html = str_replace_once('$[['.$i.']]', $link_map[$j], $html); - } else { - $html = str_replace_once('$[['.$i.']]', $path_links[$i], $html); - } - } - } - - return $html; -} - -function enterIcon() { -return << - - -SVG; -} - -function renderMoonIcon($ctx) { -return << -SVG; -} diff --git a/skin/error.phps b/skin/error.phps new file mode 100644 index 0000000..8f7e4c7 --- /dev/null +++ b/skin/error.phps @@ -0,0 +1,23 @@ + + $code $title + +

$code $title

+ {$ctx->if_true($message, + '

'.$message.'

' + )} + + +HTML; + +} \ No newline at end of file diff --git a/skin/error.skin.php b/skin/error.skin.php deleted file mode 100644 index 8f7e4c7..0000000 --- a/skin/error.skin.php +++ /dev/null @@ -1,23 +0,0 @@ - - $code $title - -

$code $title

- {$ctx->if_true($message, - '

'.$message.'

' - )} - - -HTML; - -} \ No newline at end of file diff --git a/skin/main.phps b/skin/main.phps new file mode 100644 index 0000000..3ce9985 --- /dev/null +++ b/skin/main.phps @@ -0,0 +1,241 @@ +indexEmtpy() : $ctx->indexBlog($posts); +} + +function indexEmtpy($ctx): string { +return << + {$ctx->lang('blog_no')} + {$ctx->if_admin(''.$ctx->lang('write').'')} + +HTML; +} + +function indexBlog($ctx, array $posts): string { +return << +
+ all posts + {$ctx->if_admin( + ' + new + uploads + ' + )} +
+ {$ctx->indexPostsTable($posts)} + +HTML; +} + +function indexPostsTable($ctx, array $posts): string { +$ctx->year = 3000; +return << + + {$ctx->for_each($posts, fn($post) => $ctx->indexPostRow( + $post->getYear(), + $post->visible, + $post->getDate(), + $post->getUrl(), + $post->title + ))} +
+ +HTML; +} + +function indexPostRow($ctx, $year, $is_visible, $date, $url, $title): string { +return <<if_true($ctx->year > $year, $ctx->indexYearLine, $year)} + + + {$date} + + + {$title} + + +HTML; +} + +function indexYearLine($ctx, $year): string { +$ctx->year = $year; +return << + {$year} + + +HTML; +} + + +// contacts page +// ------------- + +function contacts($ctx, $email) { +return << + + +
Feel free to contact me by any of the following means:
+ + + + Email: + + {$email} +
Please use PGP.
+ + + + Tox ID: + 4F6E82D285B342CAE83687FA63F1B083A9FD053C8BE08C709E25491C74E6016CB52C987692C3 + + + Libera.Chat: + ch1p + + +HTML; + +} + + +// any page +// -------- + +function page($ctx, $page_url, $short_name, $unsafe_html) { +$html = << + {$ctx->if_admin($ctx->pageAdminLinks, $page_url, $short_name)} +
{$unsafe_html}
+ +HTML; + +return [$html, markdownThemeChangeListener()]; +} + +function pageAdminLinks($ctx, $url, $short_name) { +return << + {$ctx->lang('edit')} + {$ctx->lang('delete')} + +HTML; + +} + + +// post page +// --------- + +function post($ctx, $id, $title, $unsafe_html, $unsafe_toc_html, $date, $visible, $url, $tags, $email, $urlencoded_reply_subject) { +$html = << +
+
+
+

{$title}

+ + +
+
{$unsafe_html}
+
+ {$ctx->if_true($unsafe_toc_html, $ctx->postToc, $unsafe_toc_html)} +
+ + +
+ {$ctx->langRaw('blog_comments_text', $email, $urlencoded_reply_subject)} +
+HTML; + +return [$html, markdownThemeChangeListener()]; +} + +function postToc($ctx, $unsafe_toc_html) { +return << +
+
+
{$ctx->lang('toc')}
+ {$unsafe_toc_html} +
+
+ +HTML; + +} + +function postAdminLinks($ctx, $url, $id) { +return <<{$ctx->lang('edit')} +{$ctx->lang('delete')} +HTML; +} + +function postTag($ctx, $url, $name) { +return <<#{$name} +HTML; +} + +function markdownThemeChangeListener() { +return << div'); + if (!div) { + console.warn('could not found a>div on this node:', node); + continue; + } + var style = div.getAttribute('style'); + if (isDark) { + style = style.replace(/(a[\d]+x[\d]+)\.jpg/, '$1_dark.jpg'); + } else { + style = style.replace(/(a[\d]+x[\d]+)_dark\.jpg/, '$1.jpg'); + } + div.setAttribute('style', style); + } +}); +JS; +} + + +// tag page +// -------- + +function tag($ctx, $count, $posts, $tag) { +if (!$count) + return << + {$ctx->lang('blog_tag_not_found')} + +HTML; + +return << +
#{$tag}
+ {$ctx->indexPostsTable($posts)} + +HTML; +} diff --git a/skin/main.skin.php b/skin/main.skin.php deleted file mode 100644 index 3ce9985..0000000 --- a/skin/main.skin.php +++ /dev/null @@ -1,241 +0,0 @@ -indexEmtpy() : $ctx->indexBlog($posts); -} - -function indexEmtpy($ctx): string { -return << - {$ctx->lang('blog_no')} - {$ctx->if_admin(''.$ctx->lang('write').'')} - -HTML; -} - -function indexBlog($ctx, array $posts): string { -return << -
- all posts - {$ctx->if_admin( - ' - new - uploads - ' - )} -
- {$ctx->indexPostsTable($posts)} - -HTML; -} - -function indexPostsTable($ctx, array $posts): string { -$ctx->year = 3000; -return << - - {$ctx->for_each($posts, fn($post) => $ctx->indexPostRow( - $post->getYear(), - $post->visible, - $post->getDate(), - $post->getUrl(), - $post->title - ))} -
- -HTML; -} - -function indexPostRow($ctx, $year, $is_visible, $date, $url, $title): string { -return <<if_true($ctx->year > $year, $ctx->indexYearLine, $year)} - - - {$date} - - - {$title} - - -HTML; -} - -function indexYearLine($ctx, $year): string { -$ctx->year = $year; -return << - {$year} - - -HTML; -} - - -// contacts page -// ------------- - -function contacts($ctx, $email) { -return << - - -
Feel free to contact me by any of the following means:
- - - - Email: - - {$email} -
Please use PGP.
- - - - Tox ID: - 4F6E82D285B342CAE83687FA63F1B083A9FD053C8BE08C709E25491C74E6016CB52C987692C3 - - - Libera.Chat: - ch1p - - -HTML; - -} - - -// any page -// -------- - -function page($ctx, $page_url, $short_name, $unsafe_html) { -$html = << - {$ctx->if_admin($ctx->pageAdminLinks, $page_url, $short_name)} -
{$unsafe_html}
- -HTML; - -return [$html, markdownThemeChangeListener()]; -} - -function pageAdminLinks($ctx, $url, $short_name) { -return << - {$ctx->lang('edit')} - {$ctx->lang('delete')} - -HTML; - -} - - -// post page -// --------- - -function post($ctx, $id, $title, $unsafe_html, $unsafe_toc_html, $date, $visible, $url, $tags, $email, $urlencoded_reply_subject) { -$html = << -
-
-
-

{$title}

- - -
-
{$unsafe_html}
-
- {$ctx->if_true($unsafe_toc_html, $ctx->postToc, $unsafe_toc_html)} -
- - -
- {$ctx->langRaw('blog_comments_text', $email, $urlencoded_reply_subject)} -
-HTML; - -return [$html, markdownThemeChangeListener()]; -} - -function postToc($ctx, $unsafe_toc_html) { -return << -
-
-
{$ctx->lang('toc')}
- {$unsafe_toc_html} -
-
- -HTML; - -} - -function postAdminLinks($ctx, $url, $id) { -return <<{$ctx->lang('edit')} -{$ctx->lang('delete')} -HTML; -} - -function postTag($ctx, $url, $name) { -return <<#{$name} -HTML; -} - -function markdownThemeChangeListener() { -return << div'); - if (!div) { - console.warn('could not found a>div on this node:', node); - continue; - } - var style = div.getAttribute('style'); - if (isDark) { - style = style.replace(/(a[\d]+x[\d]+)\.jpg/, '$1_dark.jpg'); - } else { - style = style.replace(/(a[\d]+x[\d]+)_dark\.jpg/, '$1.jpg'); - } - div.setAttribute('style', style); - } -}); -JS; -} - - -// tag page -// -------- - -function tag($ctx, $count, $posts, $tag) { -if (!$count) - return << - {$ctx->lang('blog_tag_not_found')} - -HTML; - -return << -
#{$tag}
- {$ctx->indexPostsTable($posts)} - -HTML; -} diff --git a/skin/markdown.phps b/skin/markdown.phps new file mode 100644 index 0000000..58801f5 --- /dev/null +++ b/skin/markdown.phps @@ -0,0 +1,43 @@ + + {$name} + {$ctx->if_true($note, ''.$note.'')} + {$size} + +HTML; +} + +function image($ctx, + // options + $align, $nolabel, $w, $padding_top, $may_have_alpha, + // image data + $direct_url, $url, $note) { +return << +
+ +
+
+ {$ctx->if_true( + $note != '' && !$nolabel, + '
'.$note.'
' + )} +
+ +HTML; +} + +function video($ctx, $url, $w, $h) { +return << +
+ +
+ +HTML; +} \ No newline at end of file diff --git a/skin/markdown.skin.php b/skin/markdown.skin.php deleted file mode 100644 index 58801f5..0000000 --- a/skin/markdown.skin.php +++ /dev/null @@ -1,43 +0,0 @@ - - {$name} - {$ctx->if_true($note, ''.$note.'')} - {$size} - -HTML; -} - -function image($ctx, - // options - $align, $nolabel, $w, $padding_top, $may_have_alpha, - // image data - $direct_url, $url, $note) { -return << -
- -
-
- {$ctx->if_true( - $note != '' && !$nolabel, - '
'.$note.'
' - )} -
- -HTML; -} - -function video($ctx, $url, $w, $h) { -return << -
- -
- -HTML; -} \ No newline at end of file diff --git a/skin/rss.phps b/skin/rss.phps new file mode 100644 index 0000000..0806182 --- /dev/null +++ b/skin/rss.phps @@ -0,0 +1,29 @@ + + + + {$title} + {$link} + + + {$ctx->for_each($items, fn($item) => $ctx->item(...$item))} + + +HTML; +} + +function item($ctx, $title, $link, $pub_date, $description) { +return << + {$title} + {$link} + {$pub_date} + {$description} + +HTML; +} \ No newline at end of file diff --git a/skin/rss.skin.php b/skin/rss.skin.php deleted file mode 100644 index 0806182..0000000 --- a/skin/rss.skin.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - {$title} - {$link} - - - {$ctx->for_each($items, fn($item) => $ctx->item(...$item))} - - -HTML; -} - -function item($ctx, $title, $link, $pub_date, $description) { -return << - {$title} - {$link} - {$pub_date} - {$description} - -HTML; -} \ No newline at end of file -- cgit v1.2.3