• Laravel 博客开发|导入 md 博客文章


    我之前的博客是使用 Hugo 和 Github 搭建的,写了 50 多篇博客,现在使用 Laravel 和 Bulma 重新开发了博客,新博客的文章是存在数据库的,而原来的博客是 md 文件,我想保留原来写的博客文章,又不想一篇一篇的添加,所以我需要写程序,导入 md 文件创建博客文章并保存到数据库。

    md 文件示例:

    
    欢迎来到从零开发个人博客日志的第 6 天,这个系列涵盖了我在公众场合从零开发个人博客应用的旅程,这是一个大胆的尝试。如果你错过了第 5 天,可以在[这里查看](https://www.sevdot.com/post/blog-development-from-zero-five-day)。
    ## 进度
    目前整个博客应用的功能已经开发完,接下来打算整理整理发布上线,这一刻还是挺开心的,在业余时间开发了一个小项目,并且全程写博客记录。
    
    • 1
    • 2
    • 3
    • 4

    可以看到,博客文章的标题、日期和分类是包裹在两个 --- 里面,是 YAML 格式的内容,外面的内容才是博客文章的正文。

    现在来理一理,将这些 md 文件生成对应的博客文章保存到数据库需要做的事情:

    1. 将所有 md 文件压缩成一个 zip 压缩包。
    2. 上传 zip 压缩包并解压
    3. 读取解压得到的所有 md 文件
    4. 解析 md 文件里面的内容。
    5. 批量创建文章

    上传 zip 文件

    1. 添加表单

    运行如下命令创建上传文件表单:

    php artisan admin:form ImportArticleForm
    
    • 1

    替换为如下内容:
    app/Admin/Forms/ImportArticleForm.php

     namespace App\Admin\Forms;
    
    use Dcat\Admin\Widgets\Form;
    
    class ImportArticleForm extends Form
    {
        public function handle(array $input)
        {
            return $this->response()->success('导入成功')->refresh();
        }
    
        public function form()
        {
            $this->file('zip','压缩包')->required();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3. 添加动作

    运行如下命令添加动作:

    php artisan admin:action
    
    • 1
    Which type of action would you like to make?:
    [0] default
    [1] grid-batch
    [2] grid-row
    [3] grid-tool
    [4] form-tool
    [5] show-tool
    [6] tree-row
    [7] tree-tool
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输入 3 选择 grid-tool,接着输入名称:ImportArticleAction,替换为如下内容:
    app/Admin/Actions/Grid/ImportArticleAction.php

    <?php namespace App\Admin\Actions\Grid;
    
    use App\Admin\Forms\ImportArticleForm;
    use Dcat\Admin\Grid\RowAction;
    use Dcat\Admin\Widgets\Modal;
    
    class ImportArticle extends RowAction
    {
        /**
         * @return string
         */
    	protected $title = '导入文章';
    
        public function render()
        {
            $form = ImportArticleForm::make();
    
            return Modal::make()
                ->lg()
                ->title($this->title)
                ->body($form)
                ->button('');
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3. 修改控制器

    修改管理后台文章控制器,在 grid方法添加如下内容:
    app/Admin/Controllers/ArticlesController.php

    $grid->tools(function ($tools) {
        $tools->append(new ImportArticleAction());
    });
    
    • 1
    • 2
    • 3

    打开文章管理会看到多一个导入文章的按钮,点击按钮会弹出一个框,如下所示:
    在这里插入图片描述

    选择文件后,点击上传就会把文件上传到 storage/app/public/files目录下。

    解压 zip 文件

    ImportArticleForm.php表单中添加 extract方法。
    app/Admin/Forms/ImportArticleForm.php

    .
    .
    .  
    public function extract($file){
        $zipper= new \ZipArchive();
        $zipper->open($file);
        $targetPath=storage_path('app/public/blog');
        $zipper->extractTo($targetPath);
        $zipper->close();
        return $targetPath;
    }
    .
    .
    .  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    上面的代码是将指定的压缩文件解压到指定的目录。

    handle 方法中调用:

    .
    .
    .  
    public function handle(array $input)
    {
        $file=Arr::last(explode(',',$input['zip']));
        $filePath=storage_path('app/public/').$file;
        $blogPath=$this->extract($filePath);
        return $this->response()->success('导入成功')->refresh();
    }
    .
    .
    .  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    批量创建文章

    运行如下命令安装扩展:

    composer require symfony/yaml
    
    • 1

    ImportArticleForm.php表单中添加 batchAddArticle方法。
    app/Admin/Forms/ImportArticleForm.php

    public function batchAddArticle($path){
    $files = File::files($path);
    foreach ($files as $key=>$file){
        $content = $file->getContents();
        preg_match_all('/---\n(.*?)---\n/s',$content,$yamlArr);
        $yaml = $yamlArr[1][0];
        $meta=Yaml::parse($yaml);
        $datetime=date('Y-m-d H:i:s',$meta['date']);
        $category=Arr::last($meta['categories']);
        $column = Column::firstOrCreate(['name'=>$category]);
        $articleContent=str_replace($yamlArr[0],'',$content);
        Article::create([
            'column_id'=>$column->id,
            'title'=>$meta['title'],
            'content'=>$articleContent,
            'created_at'=>$datetime,
            'updated_at'=>$datetime,
        ]);
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    上面的代码逻辑:

    1. 上面已经将 zip 压缩包解压到指定的目录,使用 File::files()方法可以获取目录下所有的文件,以数组返回。
    $files = File::files($blogPath);
    
    • 1
    1. 遍历文件数组,使用 getContents方法得到文件内容。
    $content = $file->getContents();
    
    • 1
    1. 获取两个 ---里面的 YAML 格式的内容。
      preg_match_all('/---\n(.*?)---\n/s',$content,$yamlArr);
      $yaml = $yamlArr[1][0];
    
    • 1
    • 2
    1. 使用 symfony/yaml扩展解析 YAML 格式的内容。
    $meta=Yaml::parse($yaml);
    
    • 1

    解析后会返回一个数组,如下所示:

    array:4 [
      "title" => "Laravel 博客开发|Laravel 项目中安装和使用 Bulma"
      "date" => 1650565800
      "lastmod" => 1650565800
      "categories" => array:1 [
        0 => "开发日志"
      ]
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 组装数据并创建博客文章:
     Article::create([
        'column_id'=>$column->id,
        'title'=>$meta['title'],
        'content'=>$articleContent,
        'created_at'=>$datetime,
        'updated_at'=>$datetime,
    ]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    handle 方法中调用:

    public function handle(array $input)
    {
        $file=Arr::last(explode(',',$input['zip']));
        $filePath=storage_path('app/public/').$file;
        // 解压
        $blogPath=$this->extract($filePath);
        // 批量创建文章
        $this->batchAddArticle($blogPath);
        return $this->response()->success('导入成功')->refresh();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    经过上面的处理,很轻松的就把之前的 md 文件的文章导入到现有的博客里面。

  • 相关阅读:
    迅镭激光GI系列高功率激光切割机成功中标覆铜板龙头企业HZ公司
    Vue Router - 路由的使用、两种切换方式、两种传参方式、嵌套方式
    orderby是如何工作的?
    Java装饰者模式详解:为对象动态添加功能
    人工智能在医疗领域的革命性应用
    MySQL学习笔记7
    VUE3实现个人网站模板源码
    Win11下无法打开丛林之狐,提示未检测到DirectX 8.1
    SpringBoot和SpringMVC的区别
    AlexNet—论文分析及复现
  • 原文地址:https://blog.csdn.net/u010212601/article/details/126519133