From f7bfdf58def6aadc922e1632f407d1418269a0d7 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sat, 9 Jul 2022 19:40:17 +0300 Subject: initial --- skin/admin.skin.php | 344 +++++++++++++++++++++++++++++++++++++++++++++++++ skin/base.skin.php | 190 +++++++++++++++++++++++++++ skin/error.skin.php | 40 ++++++ skin/main.skin.php | 195 ++++++++++++++++++++++++++++ skin/markdown.skin.php | 43 +++++++ skin/rss.skin.php | 29 +++++ 6 files changed, 841 insertions(+) create mode 100644 skin/admin.skin.php create mode 100644 skin/base.skin.php create mode 100644 skin/error.skin.php create mode 100644 skin/main.skin.php create mode 100644 skin/markdown.skin.php create mode 100644 skin/rss.skin.php (limited to 'skin') diff --git a/skin/admin.skin.php b/skin/admin.skin.php new file mode 100644 index 0000000..f03d7ce --- /dev/null +++ b/skin/admin.skin.php @@ -0,0 +1,344 @@ + + +
+
{$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, + string|Stringable|null $post_url = null, + ?int $post_id = null): array { +$form_url = !$is_edit ? '/write/' : $post_url.'edit/'; + +$html = <<if_true($error_code, '
'.$ctx->lang('err_blog_'.$error_code).'
')} +{$ctx->if_true($saved, '
'.$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, '
'.$ctx->lang('err_pages_'.$error_code).'
')} +{$ctx->if_true($saved, '
'.$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.skin.php b/skin/base.skin.php new file mode 100644 index 0000000..b0ebac3 --- /dev/null +++ b/skin/base.skin.php @@ -0,0 +1,190 @@ + + + + + + + + {$title} + {$ctx->renderMeta($meta)} + {$ctx->renderStatic($static)} + + if_true($opts['full_width'], ' class="full-width"')}> + {$ctx->renderHeader(renderLogo($ctx, $opts['logo_path_map'], $opts['logo_link_map']))} +
+
{$unsafe_body}
+
+ {$ctx->if_true($js != '' || !empty($lang) || $opts['dynlogo_enabled'], + $ctx->renderScript, $js, $unsafe_lang, $opts['dynlogo_enabled'])} + + + +HTML; +} + +function renderScript($ctx, $unsafe_js, $unsafe_lang, $enable_dynlogo) { +return << +{$ctx->if_true($unsafe_js, '(function(){'.$unsafe_js.'})();')} +{$ctx->if_true($unsafe_lang, 'extend(__lang, '.$unsafe_lang.');')} +{$ctx->if_true($enable_dynlogo, 'DynamicLogo.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) { + global $config; + $html = []; + foreach ($static as $name) { + // list($name, $options) = $item; + $version = $config['is_dev'] ? time() : $config['static'][substr($name, 1)] ?? 'notfound'; + if (str_ends_with($name, '.js')) + $html[] = jsLink($name, $version); + else if (str_ends_with($name, '.css')) + $html[] = cssLink($name, $version/*, $options*/); + } + return implode("\n", $html); +} + +function renderHeader($ctx, $unsafe_logo_html) { + return << +
+ +
+ blog + projects + git + misc + contacts + {$ctx->if_admin('admin')} +
+
+ +HTML; +} + +// TODO rewrite this fcking crap +function renderLogo($ctx, array $path_map = [], array $link_map = []): string { + $uri = \RequestDispatcher::path(); + + if (!\admin::isAdmin()) { + $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 ~ 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 jsLink(string $name, $version = null): string { + if ($version !== null) + $name .= '?'.$version; + return ''; +} + +function cssLink(string $name, $version = null/*, $options = null*/): string { + global $config; + if ($config['is_dev']) { + $bname = basename($name); + if (($pos = strrpos($bname, '.'))) + $bname = substr($bname, 0, $pos); + $href = '/sass.php?name='.urlencode($bname); + } else { + $href = $name.($version !== null ? '?'.$version : ''); + } + $s = 'common(403, 'Forbidden', $message); +} + +function not_found($ctx, $message) { + return $ctx->common(404, 'Not Found', $message); +} + +function unauthorized($ctx, $message) { + return $ctx->common(401, 'Unauthorized', $message); +} + +function not_implemented($ctx, $message) { + return $ctx->common(501, 'Not Implemented', $message); +} + +function common($ctx, + int $code, + string|Stringable $title, + string|Stringable|null $message = null) { +return << + $code $title + +

$code $title

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

'.$message.'

' + )} + + + +HTML; + +} \ No newline at end of file diff --git a/skin/main.skin.php b/skin/main.skin.php new file mode 100644 index 0000000..40813b9 --- /dev/null +++ b/skin/main.skin.php @@ -0,0 +1,195 @@ +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.
+ + + + Telegram: + + @eacces +
Please use Secret Chats.
+ + + + Libera.Chat: + ch1p + + +HTML; + +} + + +// any page +// -------- + +function page($ctx, $page_url, $short_name, $unsafe_html) { +return << + {$ctx->if_admin($ctx->pageAdminLinks, $page_url, $short_name)} +
{$unsafe_html}
+ +HTML; +} + +function pageAdminLinks($ctx, $url, $short_name) { +return << + {$ctx->lang('edit')} + {$ctx->lang('delete')} + +HTML; + +} + + +// post page +// --------- + +function post($ctx, $id, $title, $unsafe_html, $date, $visible, $url, $tags, $email, $urlencoded_reply_subject) { +return << +
+

{$title}

+ + +
+
{$unsafe_html}
+ +
+ {$ctx->langRaw('blog_comments_text', $email, $urlencoded_reply_subject)} +
+HTML; +} + +function postAdminLinks($ctx, $url, $id) { +return <<{$ctx->lang('edit')} +{$ctx->lang('delete')} +HTML; +} + +function postTag($ctx, $url, $name) { +return <<#{$name} +HTML; + +} + + +// tag page +// -------- + +function tag($ctx, $count, $posts, $tag) { +if (!$count) + return << + {$ctx->lang('blog_tag_not_found')} + +HTML; + +return << +
#{$tag}
+ {$ctx->indexPostsTable($posts)} + +HTML; +} \ No newline at end of file diff --git a/skin/markdown.skin.php b/skin/markdown.skin.php new file mode 100644 index 0000000..02d3a0f --- /dev/null +++ b/skin/markdown.skin.php @@ -0,0 +1,43 @@ + + {$name} + {$ctx->if_true($note, ''.$note.'')} + {$size} + +HTML; +} + +function image($ctx, + // options + $align, $nolabel, $w, $padding_top, + // 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.skin.php b/skin/rss.skin.php new file mode 100644 index 0000000..0806182 --- /dev/null +++ b/skin/rss.skin.php @@ -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 -- cgit v1.2.3