feat: restore sablog browse modes and clean imported HTML
Keep the public site readable after import (nbsp, highlighter, wrapping code, compact pager) and finish the admin extras already in this tree: sticky levels, preview, page cache, and live llms.txt. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Blog\Support\SablogHtmlNormalizer;
|
||||
use App\Models\Post;
|
||||
use Illuminate\Console\Command;
|
||||
use League\HTMLToMarkdown\HtmlConverter;
|
||||
@@ -36,6 +37,7 @@ class ConvertContent extends Command
|
||||
]);
|
||||
|
||||
$renderer = app(\App\Blog\Services\PostContentRenderer::class);
|
||||
$normalizer = app(SablogHtmlNormalizer::class);
|
||||
|
||||
$posts = $query->get();
|
||||
if ($posts->isEmpty()) {
|
||||
@@ -49,7 +51,7 @@ class ConvertContent extends Command
|
||||
|
||||
foreach ($posts as $post) {
|
||||
// [attach=xx] 是 markdown 保留字符,先换成令牌,渲染时再解析
|
||||
$markdown = $converter->convert($renderer->toMarkdownSafeTokens($post->content));
|
||||
$markdown = $normalizer->toMarkdown((string) $post->content, $converter, $renderer);
|
||||
|
||||
if ($this->option('dry-run')) {
|
||||
$this->newLine();
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Blog\Support\SablogHtmlNormalizer;
|
||||
use App\Models\Post;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class FixImportedContent extends Command
|
||||
{
|
||||
protected $signature = 'sablog:fix-content
|
||||
{--all : Repair every post}
|
||||
{id? : Single post ID}
|
||||
{--dry-run : Preview only}';
|
||||
|
||||
protected $description = 'Clean leftover SaBlog HTML: literal , highlighter blocks, stacked docker divs';
|
||||
|
||||
public function handle(SablogHtmlNormalizer $normalizer): int
|
||||
{
|
||||
$query = Post::query();
|
||||
|
||||
if ($id = $this->argument('id')) {
|
||||
$query->where('id', $id);
|
||||
} elseif (! $this->option('all')) {
|
||||
$this->error('Pass a post ID or use --all');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$posts = $query->get();
|
||||
if ($posts->isEmpty()) {
|
||||
$this->info('No posts to repair');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$changed = 0;
|
||||
foreach ($posts as $post) {
|
||||
$cleaned = $normalizer->normalize((string) $post->content);
|
||||
if ($cleaned === $post->content) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->option('dry-run')) {
|
||||
$this->line("[{$post->id}] {$post->title}");
|
||||
continue;
|
||||
}
|
||||
|
||||
$post->content = $cleaned;
|
||||
$post->save();
|
||||
$changed++;
|
||||
}
|
||||
|
||||
$this->info($this->option('dry-run')
|
||||
? 'Preview only, nothing written'
|
||||
: "Repaired {$changed} posts");
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,18 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Blog\Services\AttachmentImporter;
|
||||
use App\Models\Category;
|
||||
use App\Models\Comment;
|
||||
use App\Models\Link;
|
||||
use App\Blog\Services\PostContentRenderer;
|
||||
use App\Blog\Support\SablogHtmlNormalizer;
|
||||
use App\Models\Post;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Support\SlugGenerator;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use League\HTMLToMarkdown\HtmlConverter;
|
||||
use PDO;
|
||||
use Spatie\Tags\Tag;
|
||||
|
||||
@@ -271,6 +270,7 @@ class SablogImport extends Command
|
||||
'keywords' => $row['keywords'] ?: null,
|
||||
'status' => $status,
|
||||
'is_sticky' => (bool) $row['stick'],
|
||||
'sticky_level' => ((bool) $row['stick']) ? 1 : 0,
|
||||
'close_comment' => (bool) $row['closecomment'],
|
||||
'read_password' => $row['readpassword'] ?: null,
|
||||
'views' => (int) $row['views'],
|
||||
@@ -362,15 +362,16 @@ class SablogImport extends Command
|
||||
{
|
||||
$this->info('转换文章内容为 Markdown ...');
|
||||
|
||||
$converter = new \League\HTMLToMarkdown\HtmlConverter([
|
||||
$converter = new HtmlConverter([
|
||||
'strip_tags' => false,
|
||||
'hard_break' => true,
|
||||
]);
|
||||
$renderer = app(\App\Blog\Services\PostContentRenderer::class);
|
||||
$renderer = app(PostContentRenderer::class);
|
||||
$normalizer = app(SablogHtmlNormalizer::class);
|
||||
|
||||
$count = 0;
|
||||
foreach (Post::query()->where('content_format', 'html')->cursor() as $post) {
|
||||
$post->content = $converter->convert($renderer->toMarkdownSafeTokens($post->content));
|
||||
$post->content = $normalizer->toMarkdown((string) $post->content, $converter, $renderer);
|
||||
$post->content_format = 'markdown';
|
||||
$post->save();
|
||||
$count++;
|
||||
|
||||
Reference in New Issue
Block a user