uploads: notes on english and russian
This commit is contained in:
parent
53d8861dbb
commit
699affded9
@ -243,13 +243,14 @@ class AdminHandler extends request_handler {
|
|||||||
set_title('$blog_upload');
|
set_title('$blog_upload');
|
||||||
render('admin/uploads',
|
render('admin/uploads',
|
||||||
error: $error,
|
error: $error,
|
||||||
uploads: $uploads);
|
uploads: $uploads,
|
||||||
|
langs: PostLanguage::cases());
|
||||||
}
|
}
|
||||||
|
|
||||||
function POST_uploads() {
|
function POST_uploads() {
|
||||||
csrf_check('addupl');
|
csrf_check('addupl');
|
||||||
|
|
||||||
list($custom_name, $note) = input('name, note');
|
list($custom_name, $note_en, $note_ru) = input('name, note_en, note_ru');
|
||||||
|
|
||||||
if (!isset($_FILES['files']))
|
if (!isset($_FILES['files']))
|
||||||
redirect('/admin/uploads/?error='.urlencode('no file'));
|
redirect('/admin/uploads/?error='.urlencode('no file'));
|
||||||
@ -266,7 +267,8 @@ class AdminHandler extends request_handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (count($files) > 1) {
|
if (count($files) > 1) {
|
||||||
$note = '';
|
$note_en = '';
|
||||||
|
$note_ru = '';
|
||||||
$custom_name = '';
|
$custom_name = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,12 +287,13 @@ class AdminHandler extends request_handler {
|
|||||||
$upload_id = uploads::add(
|
$upload_id = uploads::add(
|
||||||
$f['tmp_name'],
|
$f['tmp_name'],
|
||||||
$name,
|
$name,
|
||||||
$note);
|
$note_en,
|
||||||
|
$note_ru);
|
||||||
|
|
||||||
if (!$upload_id)
|
if (!$upload_id)
|
||||||
redirect('/admin/uploads/?error='.urlencode('failed to create upload'));
|
redirect('/admin/uploads/?error='.urlencode('failed to create upload'));
|
||||||
|
|
||||||
admin_log(new \AdminActions\UploadsAdd($upload_id, $name, $note));
|
admin_log(new \AdminActions\UploadsAdd($upload_id, $name, $note_en, $note_ru));
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect('/admin/uploads/');
|
redirect('/admin/uploads/');
|
||||||
@ -308,7 +311,10 @@ class AdminHandler extends request_handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function POST_upload_edit_note() {
|
function POST_upload_edit_note() {
|
||||||
list($id, $note) = input('i:id, note');
|
list($id, $note, $lang) = input('i:id, note, lang');
|
||||||
|
$lang = PostLanguage::tryFrom($lang);
|
||||||
|
if (!$lang)
|
||||||
|
not_found();
|
||||||
|
|
||||||
$upload = uploads::get($id);
|
$upload = uploads::get($id);
|
||||||
if (!$upload)
|
if (!$upload)
|
||||||
@ -316,16 +322,19 @@ class AdminHandler extends request_handler {
|
|||||||
|
|
||||||
csrf_check('editupl'.$id);
|
csrf_check('editupl'.$id);
|
||||||
|
|
||||||
$upload->setNote($note);
|
$upload->setNote($lang, $note);
|
||||||
|
|
||||||
admin_log(new \AdminActions\UploadsEditNote($id, $note));
|
admin_log(new \AdminActions\UploadsEditNote($id, $note, $lang->value));
|
||||||
redirect('/admin/uploads/');
|
redirect('/admin/uploads/');
|
||||||
}
|
}
|
||||||
|
|
||||||
function POST_ajax_md_preview() {
|
function POST_ajax_md_preview() {
|
||||||
ensure_xhr();
|
ensure_xhr();
|
||||||
list($md, $title, $use_image_previews) = input('md, title, b:use_image_previews');
|
list($md, $title, $use_image_previews, $lang) = input('md, title, b:use_image_previews, lang');
|
||||||
$html = markup::markdownToHtml($md, $use_image_previews);
|
$lang = PostLanguage::tryFrom($lang);
|
||||||
|
if (!$lang)
|
||||||
|
invalid_request();
|
||||||
|
$html = markup::markdownToHtml($md, $use_image_previews, $lang);
|
||||||
$ctx = skin('admin');
|
$ctx = skin('admin');
|
||||||
$html = $ctx->markdownPreview(
|
$html = $ctx->markdownPreview(
|
||||||
unsafe_html: $html,
|
unsafe_html: $html,
|
||||||
|
@ -81,7 +81,8 @@ extend(AdminWriteEditForm.prototype, {
|
|||||||
this.previewRequest.abort();
|
this.previewRequest.abort();
|
||||||
var params = {
|
var params = {
|
||||||
md: this.form.elements.text.value,
|
md: this.form.elements.text.value,
|
||||||
use_image_previews: this.isPage() ? 1 : 0
|
use_image_previews: this.isPage() ? 1 : 0,
|
||||||
|
lang: this.getCurrentLang()
|
||||||
};
|
};
|
||||||
if (this.isPost())
|
if (this.isPost())
|
||||||
params.title = this.form.elements.title.value;
|
params.title = this.form.elements.title.value;
|
||||||
|
@ -95,7 +95,13 @@
|
|||||||
font-size: $fs - 2px;
|
font-size: $fs - 2px;
|
||||||
}
|
}
|
||||||
.blog-upload-item-note {
|
.blog-upload-item-note {
|
||||||
padding: 0 0 4px;
|
padding: 8px 0 0;
|
||||||
|
> span {
|
||||||
|
background-color: $hover-hl;
|
||||||
|
padding: 1px 5px;
|
||||||
|
color: $dark-grey;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.blog-upload-item-md {
|
.blog-upload-item-md {
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
@ -376,51 +382,43 @@ body.wide .blog-post {
|
|||||||
color: $grey;
|
color: $grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog-list-table-wrap {
|
|
||||||
|
.blog-list {
|
||||||
|
&-wrap {
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
}
|
|
||||||
.blog-list-table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
.blog-list-table td {
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0 0 13px;
|
|
||||||
}
|
|
||||||
.blog-list-table tr:last-child td {
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
td.blog-item-date-cell {
|
|
||||||
width: 1px;
|
|
||||||
white-space: nowrap;
|
|
||||||
//text-align: right;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
.blog-item-date {
|
|
||||||
color: $grey;
|
|
||||||
//text-transform: lowercase;
|
|
||||||
}
|
|
||||||
td.blog-item-title-cell {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.blog-item-title {
|
|
||||||
//font-weight: bold;
|
|
||||||
}
|
|
||||||
.blog-item-row {
|
|
||||||
font-size: $fs;
|
|
||||||
line-height: 140%;
|
|
||||||
}
|
|
||||||
.blog-item-row.ishidden a.blog-item-title {
|
|
||||||
color: $fg;
|
|
||||||
}
|
|
||||||
.blog-item-row-year {
|
|
||||||
td {
|
|
||||||
padding-top: 10px;
|
|
||||||
//text-align: right;
|
|
||||||
font-size: $fs + 2px;
|
|
||||||
//letter-spacing: -0.5px;
|
|
||||||
}
|
}
|
||||||
&:first-child td {
|
|
||||||
padding-top: 0;
|
&-item {
|
||||||
|
display: block;
|
||||||
|
padding: 6px 8px;
|
||||||
|
margin-left: -8px;
|
||||||
|
margin-right: -8px;
|
||||||
|
font-size: $fs;
|
||||||
|
//line-height: 140%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: $hover-hl;
|
||||||
|
@include radius(3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-date {
|
||||||
|
color: $grey;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
&-title {
|
||||||
|
margin-left: 70px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
&.is-hidden &-title {
|
||||||
|
color: $fg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blog-list-title {
|
||||||
|
font-size: $fs + 2px;
|
||||||
|
padding-top: 14px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
&:first-child { padding-top: 0; }
|
||||||
|
}
|
||||||
|
@ -282,9 +282,10 @@ table.contacts div.note {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
.md-image-note {
|
.md-image-note {
|
||||||
line-height: 150%;
|
line-height: 130%;
|
||||||
color: $dark-grey;
|
color: $dark-grey;
|
||||||
padding: 2px 0 4px;
|
padding: 8px 0 4px;
|
||||||
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md-video video {
|
.md-video video {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@import '../vars';
|
@import '../vars';
|
||||||
|
|
||||||
$form-field-label-width: 120px;
|
$form-field-label-width: 160px;
|
||||||
|
|
||||||
form { display: block; margin: 0; }
|
form { display: block; margin: 0; }
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ class UploadsAdd extends BaseAction {
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
public int $uploadId,
|
public int $uploadId,
|
||||||
public string $name,
|
public string $name,
|
||||||
public string $note
|
public string $noteEn,
|
||||||
|
public string $noteRu
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
}
|
}
|
@ -6,7 +6,8 @@ class UploadsEditNote extends BaseAction {
|
|||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public int $uploadId,
|
public int $uploadId,
|
||||||
public string $note
|
public string $note,
|
||||||
|
public string $lang
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
}
|
}
|
@ -1,12 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'engine/skin.php';
|
||||||
|
require_once 'lib/posts.php';
|
||||||
|
|
||||||
class MyParsedown extends ParsedownExtended {
|
class MyParsedown extends ParsedownExtended {
|
||||||
|
|
||||||
protected array $options;
|
protected array $options;
|
||||||
|
|
||||||
function __construct(
|
function __construct(
|
||||||
?array $opts = null,
|
?array $opts = null,
|
||||||
protected bool $useImagePreviews = false
|
protected bool $useImagePreviews = false,
|
||||||
|
protected ?PostLanguage $lang = null,
|
||||||
) {
|
) {
|
||||||
$parsedown_opts = [
|
$parsedown_opts = [
|
||||||
'tables' => [
|
'tables' => [
|
||||||
@ -44,15 +48,13 @@ class MyParsedown extends ParsedownExtended {
|
|||||||
unset($result['element']['text']);
|
unset($result['element']['text']);
|
||||||
|
|
||||||
$ctx = self::getSkinContext();
|
$ctx = self::getSkinContext();
|
||||||
$result['element']['rawHtml'] = $ctx->fileupload($upload->name, $upload->getDirectUrl(), $upload->note, $upload->getSize());
|
$result['element']['rawHtml'] = $ctx->fileupload($upload->name, $upload->getDirectUrl(), $upload->noteRu, $upload->getSize());
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function inlineImage($excerpt) {
|
protected function inlineImage($excerpt) {
|
||||||
global $config;
|
|
||||||
|
|
||||||
if (preg_match('/^{image:([\w]{8}),(.*?)}{\/image}/', $excerpt['text'], $matches)) {
|
if (preg_match('/^{image:([\w]{8}),(.*?)}{\/image}/', $excerpt['text'], $matches)) {
|
||||||
$random_id = $matches[1];
|
$random_id = $matches[1];
|
||||||
|
|
||||||
@ -115,7 +117,7 @@ class MyParsedown extends ParsedownExtended {
|
|||||||
|
|
||||||
url: $image_url,
|
url: $image_url,
|
||||||
direct_url: $image->getDirectUrl(),
|
direct_url: $image->getDirectUrl(),
|
||||||
note: $image->note
|
note: $this->lang !== null && $this->lang == PostLanguage::Russian ? $image->noteRu : $image->noteEn
|
||||||
);
|
);
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once 'lib/ext/MyParsedown.php';
|
require_once 'lib/ext/MyParsedown.php';
|
||||||
|
require_once 'lib/posts.php';
|
||||||
|
|
||||||
class markup {
|
class markup {
|
||||||
|
|
||||||
public static function markdownToHtml(string $md, bool $use_image_previews = true): string {
|
public static function markdownToHtml(string $md,
|
||||||
$pd = new MyParsedown(useImagePreviews: $use_image_previews);
|
bool $use_image_previews = true,
|
||||||
|
?PostLanguage $lang = null): string {
|
||||||
|
$pd = new MyParsedown(useImagePreviews: $use_image_previews, lang: $lang);
|
||||||
return $pd->text($md);
|
return $pd->text($md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class Post extends model {
|
|||||||
protected array $texts = [];
|
protected array $texts = [];
|
||||||
|
|
||||||
public function addText(PostLanguage $lang, string $title, string $md, bool $toc): ?PostText {
|
public function addText(PostLanguage $lang, string $title, string $md, bool $toc): ?PostText {
|
||||||
$html = markup::markdownToHtml($md);
|
$html = markup::markdownToHtml($md, lang: $lang);
|
||||||
$text = markup::htmlToText($html);
|
$text = markup::htmlToText($html);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
@ -128,7 +128,7 @@ class PostText extends model {
|
|||||||
|
|
||||||
public function edit(array $fields) {
|
public function edit(array $fields) {
|
||||||
if ($fields['md'] != $this->md) {
|
if ($fields['md'] != $this->md) {
|
||||||
$fields['html'] = markup::markdownToHtml($fields['md']);
|
$fields['html'] = markup::markdownToHtml($fields['md'], lang: $this->lang);
|
||||||
$fields['text'] = markup::htmlToText($fields['html']);
|
$fields['text'] = markup::htmlToText($fields['html']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,13 +141,13 @@ class PostText extends model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function updateHtml(): void {
|
public function updateHtml(): void {
|
||||||
$html = markup::markdownToHtml($this->md);
|
$html = markup::markdownToHtml($this->md, lang: $this->lang);
|
||||||
$this->html = $html;
|
$this->html = $html;
|
||||||
DB()->query("UPDATE posts_texts SET html=? WHERE id=?", $html, $this->id);
|
DB()->query("UPDATE posts_texts SET html=? WHERE id=?", $html, $this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateText(): void {
|
public function updateText(): void {
|
||||||
$html = markup::markdownToHtml($this->md);
|
$html = markup::markdownToHtml($this->md, lang: $this->lang);
|
||||||
$text = markup::htmlToText($html);
|
$text = markup::htmlToText($html);
|
||||||
$this->text = $text;
|
$this->text = $text;
|
||||||
DB()->query("UPDATE posts_texts SET text=? WHERE id=?", $text, $this->id);
|
DB()->query("UPDATE posts_texts SET text=? WHERE id=?", $text, $this->id);
|
||||||
|
@ -19,7 +19,7 @@ class uploads {
|
|||||||
return in_array($ext, UPLOADS_ALLOWED_EXTENSIONS);
|
return in_array($ext, UPLOADS_ALLOWED_EXTENSIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function add(string $tmp_name, string $name, string $note): ?int {
|
static function add(string $tmp_name, string $name, string $note_en, string $note_ru): ?int {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
$name = sanitize_filename($name);
|
$name = sanitize_filename($name);
|
||||||
@ -44,7 +44,8 @@ class uploads {
|
|||||||
'image' => (int)$is_image,
|
'image' => (int)$is_image,
|
||||||
'image_w' => $image_w,
|
'image_w' => $image_w,
|
||||||
'image_h' => $image_h,
|
'image_h' => $image_h,
|
||||||
'note' => $note,
|
'note_ru' => $note_ru,
|
||||||
|
'note_en' => $note_en,
|
||||||
'downloads' => 0,
|
'downloads' => 0,
|
||||||
])) {
|
])) {
|
||||||
return null;
|
return null;
|
||||||
@ -163,7 +164,8 @@ class Upload extends model {
|
|||||||
public int $image; // TODO: remove
|
public int $image; // TODO: remove
|
||||||
public int $imageW;
|
public int $imageW;
|
||||||
public int $imageH;
|
public int $imageH;
|
||||||
public string $note;
|
public string $noteRu;
|
||||||
|
public string $noteEn;
|
||||||
|
|
||||||
function getDirectory(): string {
|
function getDirectory(): string {
|
||||||
global $config;
|
global $config;
|
||||||
@ -212,9 +214,9 @@ class Upload extends model {
|
|||||||
return $md;
|
return $md;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNote(string $note) {
|
function setNote(PostLanguage $lang, string $note) {
|
||||||
$db = DB();
|
$db = DB();
|
||||||
$db->query("UPDATE uploads SET note=? WHERE id=?", $note, $this->id);
|
$db->query("UPDATE uploads SET note_{$lang->value}=? WHERE id=?", $note, $this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isImage(): bool {
|
function isImage(): bool {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace skin\admin;
|
namespace skin\admin;
|
||||||
|
|
||||||
|
use PostLanguage;
|
||||||
use Stringable;
|
use Stringable;
|
||||||
use function skin\base\layout;
|
use function skin\base\layout;
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ HTML;
|
|||||||
// uploads page
|
// uploads page
|
||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
function uploads($ctx, $uploads, $error) {
|
function uploads($ctx, $uploads, $error, array $langs) {
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
{$ctx->if_true($error, $ctx->formError, $error)}
|
{$ctx->if_true($error, $ctx->formError, $error)}
|
||||||
|
|
||||||
@ -91,12 +92,8 @@ return <<<HTML
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-field-wrap clearfix">
|
{$ctx->for_each($langs,
|
||||||
<div class="form-field-label">{$ctx->lang('blog_upload_form_note')}:</div>
|
fn($l) => $ctx->uploads_form_note_field($l))}
|
||||||
<div class="form-field">
|
|
||||||
<input type="text" name="note" size="55">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-field-wrap clearfix">
|
<div class="form-field-wrap clearfix">
|
||||||
<div class="form-field-label"></div>
|
<div class="form-field-label"></div>
|
||||||
@ -108,12 +105,14 @@ return <<<HTML
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="blog-upload-list">
|
<div class="blog-upload-list">
|
||||||
{$ctx->for_each($uploads, fn($u) => $ctx->uploadsItem(
|
{$ctx->for_each($uploads, fn($u) => $ctx->uploads_item(
|
||||||
id: $u->id,
|
id: $u->id,
|
||||||
name: $u->name,
|
name: $u->name,
|
||||||
direct_url: $u->getDirectUrl(),
|
direct_url: $u->getDirectUrl(),
|
||||||
note: $u->note,
|
note_ru: $u->noteRu,
|
||||||
addslashes_note: $u->note,
|
note_en: $u->noteEn,
|
||||||
|
addslashes_note_ru: $u->noteRu,
|
||||||
|
addslashes_note_en: $u->noteEn,
|
||||||
markdown: $u->getMarkdown(),
|
markdown: $u->getMarkdown(),
|
||||||
size: $u->getSize(),
|
size: $u->getSize(),
|
||||||
))}
|
))}
|
||||||
@ -121,17 +120,35 @@ return <<<HTML
|
|||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadsItem($ctx, $id, $direct_url, $note, $addslashes_note, $markdown, $name, $size) {
|
function uploads_form_note_field($ctx, PostLanguage $lang) {
|
||||||
|
$label = $ctx->lang('blog_upload_form_note');
|
||||||
|
$label .= ' ('.$lang->name.')';
|
||||||
|
|
||||||
|
return <<<HTML
|
||||||
|
<div class="form-field-wrap clearfix">
|
||||||
|
<div class="form-field-label">{$label}:</div>
|
||||||
|
<div class="form-field">
|
||||||
|
<input type="text" name="note_{$lang->value}" size="55">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploads_item($ctx, $id, $direct_url, $note_en, $note_ru, $addslashes_note_en, $addslashes_note_ru, $markdown, $name, $size) {
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<div class="blog-upload-item">
|
<div class="blog-upload-item">
|
||||||
<div class="blog-upload-item-actions">
|
<div class="blog-upload-item-actions">
|
||||||
<a href="javascript:void(0)" onclick="var mdel = ge('upload{$id}_md'); mdel.style.display = (mdel.style.display === 'none' ? 'block' : 'none')">{$ctx->lang('blog_upload_show_md')}</a>
|
<a href="javascript:void(0)" onclick="var mdel = ge('upload{$id}_md'); mdel.style.display = (mdel.style.display === 'none' ? 'block' : 'none')">{$ctx->lang('blog_upload_show_md')}</a>
|
||||||
| <a href="javascript:void(0)" onclick="BlogUploadList.submitNoteEdit('/admin/uploads/edit_note/{$id}/?token={$ctx->csrf('editupl'.$id)}', prompt('Note:', '{$addslashes_note}'))">Edit note</a>
|
| <a href="javascript:void(0)" onclick="BlogUploadList.submitNoteEdit('/admin/uploads/edit_note/{$id}/?lang=ru&token={$ctx->csrf('editupl'.$id)}', prompt('Note (Ru):', '{$addslashes_note_ru}'))">Edit note Ru</a>
|
||||||
|
| <a href="javascript:void(0)" onclick="BlogUploadList.submitNoteEdit('/admin/uploads/edit_note/{$id}/?lang=en&token={$ctx->csrf('editupl'.$id)}', prompt('Note (En):', '{$addslashes_note_en}'))">Edit note En</a>
|
||||||
| <a href="/admin/uploads/delete/{$id}/?token={$ctx->csrf('delupl'.$id)}" onclick="return confirm('{$ctx->lang('blog_upload_delete_confirmation')}')">{$ctx->lang('blog_upload_delete')}</a>
|
| <a href="/admin/uploads/delete/{$id}/?token={$ctx->csrf('delupl'.$id)}" onclick="return confirm('{$ctx->lang('blog_upload_delete_confirmation')}')">{$ctx->lang('blog_upload_delete')}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="blog-upload-item-name"><a href="{$direct_url}">{$name}</a></div>
|
<div class="blog-upload-item-name"><a href="{$direct_url}">{$name}</a></div>
|
||||||
{$ctx->if_true($note, '<div class="blog-upload-item-note">'.$note.'</div>')}
|
|
||||||
<div class="blog-upload-item-info">{$size}</div>
|
<div class="blog-upload-item-info">{$size}</div>
|
||||||
|
{$ctx->if_true($note_en,
|
||||||
|
fn() => '<div class="blog-upload-item-note"><span>En</span>'.$note_en.'</div>')}
|
||||||
|
{$ctx->if_true($note_ru,
|
||||||
|
fn() => '<div class="blog-upload-item-note"><span>Ru</span>'.$note_ru.'</div>')}
|
||||||
<div class="blog-upload-item-md" id="upload{$id}_md" style="display: none">
|
<div class="blog-upload-item-md" id="upload{$id}_md" style="display: none">
|
||||||
<input type="text" value="{$markdown}" onclick="this.select()" readonly size="30">
|
<input type="text" value="{$markdown}" onclick="this.select()" readonly size="30">
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,36 +45,35 @@ HTML;
|
|||||||
|
|
||||||
function articles($ctx, array $posts, PostLanguage $selected_lang): string {
|
function articles($ctx, array $posts, PostLanguage $selected_lang): string {
|
||||||
if (empty($posts))
|
if (empty($posts))
|
||||||
return $ctx->articlesEmpty($selected_lang);
|
return $ctx->articles_empty($selected_lang);
|
||||||
|
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<div class="blog-list">
|
<div class="blog-list">
|
||||||
{$ctx->articlesPostsTable($posts, $selected_lang)}
|
{$ctx->articles_posts_table($posts, $selected_lang)}
|
||||||
</div>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function articlesEmpty($ctx, PostLanguage $selected_lang) {
|
function articles_empty($ctx, PostLanguage $selected_lang) {
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<div class="empty">
|
<div class="empty">
|
||||||
{$ctx->lang('blog_no')}
|
{$ctx->lang('blog_no')}
|
||||||
{$ctx->articlesRightLinks($selected_lang->value)}
|
{$ctx->articles_right_links($selected_lang->value)}
|
||||||
</div>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function articlesPostsTable($ctx, array $posts, PostLanguage $selected_lang): string {
|
function articles_posts_table($ctx, array $posts, PostLanguage $selected_lang): string {
|
||||||
$ctx->year = 3000;
|
$ctx->year = 3000;
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<div class="blog-list-table-wrap">
|
<div class="blog-list-wrap">
|
||||||
<table class="blog-list-table" width="100%" cellspacing="0" cellpadding="0">
|
{$ctx->for_each($posts,
|
||||||
{$ctx->for_each($posts, fn($post, $i) => $ctx->articlesPostRow($i, $post, $selected_lang))}
|
fn($post, $i) => $ctx->articles_post_row($i, $post, $selected_lang))}
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function articlesPostRow($ctx, int $index, Post $post, PostLanguage $selected_lang): string {
|
function articles_post_row($ctx, int $index, Post $post, PostLanguage $selected_lang): string {
|
||||||
$year = $post->getYear();
|
$year = $post->getYear();
|
||||||
$date = $post->getDate();
|
$date = $post->getDate();
|
||||||
$url = $post->getUrl($selected_lang);
|
$url = $post->getUrl($selected_lang);
|
||||||
@ -83,32 +82,29 @@ $pt = $post->getText($selected_lang);
|
|||||||
$title = $pt->title;
|
$title = $pt->title;
|
||||||
|
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
{$ctx->if_true($ctx->year > $year, $ctx->articlesIndexYearLine, $year, $index === 0, $selected_lang->value)}
|
{$ctx->if_true($ctx->year > $year,
|
||||||
<tr class="blog-item-row{$ctx->if_not($post->visible, ' ishidden')}">
|
fn() => $ctx->articles_index_year_line($year, $index === 0, $selected_lang->value))}
|
||||||
<td class="blog-item-date-cell">
|
|
||||||
<span class="blog-item-date">{$date}</span>
|
<a href="{$url}" class="blog-list-item clearfix{$ctx->if_not($post->visible, ' is-hidden')}">
|
||||||
</td>
|
<div class="blog-list-item-date">{$date}</div>
|
||||||
<td class="blog-item-title-cell">
|
<div class="blog-list-item-title">{$title}</div>
|
||||||
<a class="blog-item-title" href="{$url}">{$title}</a>
|
</a>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function articlesIndexYearLine($ctx, $year, $show_right_links, string $selected_lang): string {
|
function articles_index_year_line($ctx, $year, $show_right_links, string $selected_lang): string {
|
||||||
$ctx->year = $year;
|
$ctx->year = $year;
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<tr class="blog-item-row-year">
|
<div class="blog-list-title">
|
||||||
<td class="blog-item-date-cell"><span>{$year}</span></td>
|
{$year}
|
||||||
<td>
|
|
||||||
{$ctx->if_true($show_right_links, $ctx->articlesRightLinks($selected_lang))}
|
{$ctx->if_true($show_right_links,
|
||||||
</td>
|
fn() => $ctx->articles_right_links($selected_lang))}
|
||||||
</tr>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function articles_right_links($ctx, string $selected_lang) {
|
||||||
function articlesRightLinks($ctx, string $selected_lang) {
|
|
||||||
$links = [
|
$links = [
|
||||||
['url' => $selected_lang != 'en' ? '/articles/' : null, 'label' => lang('lang_en')],
|
['url' => $selected_lang != 'en' ? '/articles/' : null, 'label' => lang('lang_en')],
|
||||||
['url' => $selected_lang != 'ru' ? '/articles/?lang=ru' : null, 'label' => lang('lang_ru')],
|
['url' => $selected_lang != 'ru' ? '/articles/?lang=ru' : null, 'label' => lang('lang_ru')],
|
||||||
@ -119,12 +115,12 @@ if (is_admin()) {
|
|||||||
|
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<div class="blog-item-right-links">
|
<div class="blog-item-right-links">
|
||||||
{$ctx->for_each($links, fn($link, $index) => $ctx->articlesRightLink($link['url'], $link['label'], $index))}
|
{$ctx->for_each($links, fn($link, $index) => $ctx->articles_right_link($link['url'], $link['label'], $index))}
|
||||||
</div>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function articlesRightLink($ctx, $url, string $label, int $index) {
|
function articles_right_link($ctx, $url, string $label, int $index) {
|
||||||
$buf = '';
|
$buf = '';
|
||||||
if ($index > 0)
|
if ($index > 0)
|
||||||
$buf .= ' <span class="blog-links-separator">|</span> ';
|
$buf .= ' <span class="blog-links-separator">|</span> ';
|
||||||
@ -142,15 +138,15 @@ $html = <<<HTML
|
|||||||
<!--<div class="blog-post-title-nav">
|
<!--<div class="blog-post-title-nav">
|
||||||
<a href="/">{$ctx->lang('index')}</a> <span>›</span>
|
<a href="/">{$ctx->lang('index')}</a> <span>›</span>
|
||||||
</div>-->
|
</div>-->
|
||||||
{$ctx->if_admin($ctx->pageAdminLinks, $page_url, $short_name)}
|
{$ctx->if_admin($ctx->page_admin_links, $page_url, $short_name)}
|
||||||
<div class="blog-post-text">{$unsafe_html}</div>
|
<div class="blog-post-text">{$unsafe_html}</div>
|
||||||
</div>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
|
|
||||||
return [$html, markdownThemeChangeListener()];
|
return [$html, js_markdownThemeChangeListener()];
|
||||||
}
|
}
|
||||||
|
|
||||||
function pageAdminLinks($ctx, $url, $short_name) {
|
function page_admin_links($ctx, $url, $short_name) {
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<div class="page-edit-links">
|
<div class="page-edit-links">
|
||||||
<a href="{$url}edit/">{$ctx->lang('edit')}</a>
|
<a href="{$url}edit/">{$ctx->lang('edit')}</a>
|
||||||
@ -177,8 +173,8 @@ $html = <<<HTML
|
|||||||
<div class="blog-post-date">
|
<div class="blog-post-date">
|
||||||
{$ctx->if_not($visible, $ctx->lang('blog_post_hidden').' |')}
|
{$ctx->if_not($visible, $ctx->lang('blog_post_hidden').' |')}
|
||||||
{$date}
|
{$date}
|
||||||
{$ctx->if_true($other_langs, $ctx->postOtherLangs($url, $other_langs))}
|
{$ctx->if_true($other_langs, $ctx->post_other_langs($url, $other_langs))}
|
||||||
{$ctx->if_admin($ctx->postAdminLinks, $url, $id, $lang)}
|
{$ctx->if_admin($ctx->post_admin_links, $url, $id, $lang)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="blog-post-text">{$unsafe_html}</div>
|
<div class="blog-post-text">{$unsafe_html}</div>
|
||||||
@ -188,10 +184,10 @@ $html = <<<HTML
|
|||||||
</div>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
|
|
||||||
return [$html, markdownThemeChangeListener()];
|
return [$html, js_markdownThemeChangeListener()];
|
||||||
}
|
}
|
||||||
|
|
||||||
function postOtherLangs($ctx, $url, $other_langs) {
|
function post_other_langs($ctx, $url, $other_langs) {
|
||||||
$buf = '';
|
$buf = '';
|
||||||
foreach ($other_langs as $lang) {
|
foreach ($other_langs as $lang) {
|
||||||
$buf .= ' | <a href="'.$url.'?lang='.$lang.'">'.$ctx->lang('blog_read_in_'.$lang).'</a>';
|
$buf .= ' | <a href="'.$url.'?lang='.$lang.'">'.$ctx->lang('blog_read_in_'.$lang).'</a>';
|
||||||
@ -213,14 +209,14 @@ HTML;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function postAdminLinks($ctx, $url, $id, string $lang) {
|
function post_admin_links($ctx, $url, $id, string $lang) {
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
| <a href="{$url}edit/?lang={$lang}">{$ctx->lang('edit')}</a>
|
| <a href="{$url}edit/?lang={$lang}">{$ctx->lang('edit')}</a>
|
||||||
| <a href="{$url}delete/?token={$ctx->csrf('delpost'.$id)}" onclick="return confirm('{$ctx->lang('blog_post_delete_confirmation')}')">{$ctx->lang('delete')}</a>
|
| <a href="{$url}delete/?token={$ctx->csrf('delpost'.$id)}" onclick="return confirm('{$ctx->lang('blog_post_delete_confirmation')}')">{$ctx->lang('delete')}</a>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function markdownThemeChangeListener() {
|
function js_markdownThemeChangeListener() {
|
||||||
return <<<JS
|
return <<<JS
|
||||||
ThemeSwitcher.addOnChangeListener(function(isDark) {
|
ThemeSwitcher.addOnChangeListener(function(isDark) {
|
||||||
var nodes = document.querySelectorAll('.md-image-wrap');
|
var nodes = document.querySelectorAll('.md-image-wrap');
|
||||||
|
@ -23,11 +23,9 @@ return <<<HTML
|
|||||||
<a href="{$direct_url}">
|
<a href="{$direct_url}">
|
||||||
<div style="background: url('{$url}') no-repeat; background-size: contain; width: {$w}px; padding-top: {$padding_top}%;"></div>
|
<div style="background: url('{$url}') no-repeat; background-size: contain; width: {$w}px; padding-top: {$padding_top}%;"></div>
|
||||||
</a>
|
</a>
|
||||||
{$ctx->if_true(
|
|
||||||
$note != '' && !$nolabel,
|
|
||||||
'<div class="md-image-note">'.$note.'</div>'
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
{$ctx->if_true($note != '' && !$nolabel,
|
||||||
|
fn() => '<div class="md-image-note">'.$note.'</div>')}
|
||||||
</div>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user