首页编程PHPLaravel文章详细

Laravel5.4框架与Laravel-admin集成Markdown编辑器

思图网址导航 2022-07-30 13:09:07 1172

本文将使用Laravel5.4框架,开发设备为windows,使用Homestead 环境。

一、安装Laravel项目


1.安装项目:


cd ~/Homestead && vagrant up
vagrant ssh
vagrant@homestead:~$ cd Code
vagrant@homestead:~/Code$ composer create-project laravel/laravel digtime

// 或者指定版本
composer create-project --prefer-dist laravel/laravel digtime "5.5.*"

2.homestead.yaml配置


➜ ~ atom ~/.homestead/Homestead.yaml
---
ip: "192.168.10.10"
memory: 2048
cpus: 1
provider: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: ~/Code
      to: /home/vagrant/Code

sites:
    - map: digtime.app # <--- 这里,第四个项目
      to: /home/vagrant/Code/digtime/public # <--- 这里

databases:
    - digtime

variables:
    - key: APP_ENV
      value: local

# blackfire:
#     - id: foo
#       token: bar
#       client-id: foo
#       client-token: bar

# ports:
#     - send: 50000
#       to: 5000
#     - send: 7777
#       to: 777
#       protocol: udp

3.重启vagrant


修改完 *Homestead.yaml *文件后,需要重新加载配置文件信息才能生效。

➜  ~ cd Homestead
➜  Homestead git:(7924ab4) vagrant reload --provision

4.修改hosts配置文件


Hosts配置域名在mac的位置: /etc/hosts

192.168.10.10 digtime.app

5.通过域名访问


digtime.app

6.快速进入项目


cd ~/Homestead && vagrant up
vagrant ssh
cd ~/Code/digtime

二、安装项目需要的资源


1.npm安装前端包


npm install

2.artisan 生成表


执行所有未执行的迁移

php artisan migrate

回滚上一次的迁移

vagrant@homestead:~/Code/digtime$ php artisan migrate:rollback

3. artisan 命令生成权限


php artisan make:auth

4. 修改User位置


Laravel为我们默认创建的模型文件放置在 app文件夹下,为了更符合 MVC模式的开发流程,本博文统一使用 app/Models *文件夹来放置所有的模型文件。现在让我们先来创建一个 *app/Models 文件夹,并将 User.php 文件放置到其中。

$ mkdir app/Models
$ mv app/User.php app/Models/User.php

在执行完这一步的操作之后,我们还需要执行下面这两个操作:

1、修改 User.php 文件,更改** namespace**为我们新创建的文件夹路径: app/Models/User.php

<?php
namespace App\Models;
.

2、全局更改 App\User 为 App\Models\User,在** Atom中使用快捷键 **shift + cmd(ctrl) + f 来进行全局搜索替换的操作。

完成之后,点击右下角的** Replace All**按钮。

三、github 托管项目


git 初始化

vagrant@homestead:~/Code/digtime$ git init
Initialized empty Git repository in /home/vagrant/Code/digtime/.git/
vagrant@homestead:~/Code/digtime$ git add -A
> git commit -m "Initial commit"

// 将项目推到github上
> git remote add origin git@github.com:corwien/digtime.git
> git push -u origin master

// 添加分支
> git checkout master
> git checkout -b users

四、webpack打包资源


有关Laravel5.4的 webpack使用,请看我的这篇博文: Laravel5.4新特性-Laravel-mix的使用

Mix是位于 Webpack 顶层的配置层,所以要运行 Mix 任务你只需要在运行包含在默认 package.json文件中的其中某个 NPM 脚本即可:

// 1.安装package.json 包
npm install

// 2.运行所有 Mix 任务...
npm run dev

// 运行所有 Mix 任务并减少输出...
// npm run production

// 3.监控前端资源改变
npm run watch
监控前端资源改变

五、密码重置邮件发送


对密码重置邮件发送进行重构,使用sendCloud进行发送。 在 App\Models\User.php 用户 Model 方法中重写sendPasswordResetNotification($token)发送邮件的方法:

 /**
     * 重写重置密码的邮件发送通知,覆盖zhihu_app_reset_password底层的发送方法
     * 对这个类进行重写: \Illuminate\Contracts\Auth\PasswordBroker
     *  $user->sendPasswordResetNotification(
     *   $this->tokens->create($user)
     *   );
     * 类文件:Passwords\PasswordBroker
     * @param $token
     */
    public function sendPasswordResetNotification($token)
    {
        // 重构发送邮件
        (new UserMailer())->resetPassword($token, $this->email);
    }
        ```
IlluminateAuthPasswordsPasswordBroker.php

/** * Send a password reset link to a user. * * @param array $credentials * @return string */ public function sendResetLink(array $credentials) { // First we will check to see if we found a user at the given credentials and // if we did not we will redirect back to this current URI with a piece of // "flash" data in the session to indicate to the developers the errors.

    // 根据传递过来的email获取用户信息
    $user = $this->getUser($credentials);

    if (is_null($user)) {
        return static::INVALID_USER;
    }

    // Once we have the reset token, we are ready to send the message out to this
    // user with a link to reset their password. We will then redirect back to
    // the current URI having nothing set in the session to indicate errors.
    $user->sendPasswordResetNotification(
        $this->tokens->create($user)
    );

    return static::RESET_LINK_SENT;
}
IlluminateAuthPasswordsCanResetPassword.php

/** * Send the password reset notification. * * @param string $token * @return void */ public function sendPasswordResetNotification($token) { $this->notify(new ResetPasswordNotification($token)); }

最底层的发送邮件方法:
IlluminateAuthNotificationsResetPassword.php

/** * Build the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ public function toMail($notifiable) { return (new MailMessage) ->line('You are receiving this email because we received a password reset request for your account.') ->action('Reset Password', route('password.reset', $this->token)) ->line('If you did not request a password reset, no further action is required.'); }

## 六、自定义函数方法
---
在**app**目录下,创建共用的函数文件**Support/helpers.php**

![](https://image-static.segmentfault.com/912/409/912409674-58f0eb4fa9aa2_articlex)

创建方法文件之后,需要在**composer.json**文件中自动加载:

"autoload": { "files":[ "app/Support/helpers.php" ],

},
然后执行 **composer** 重新加载方法:

composer dump-autoload

## 七、Markdown编辑器
---
http://editor.integ.me/ segmentfault 家的,解析库也有:https://segmentfault.com/a/11...

https://laravel-china.org/top...

### 1.Markdown编辑器
---
Markdown编辑器:**https://simplemde.com/**

![](https://image-static.segmentfault.com/216/467/216467098-58fbfc733659f_articlex)

这个编辑器看起来挺不错,很简洁,我们可以集成在我们的项目中。

### 1.1 npm 安装
---

npm install simplemde --save

### 1.2 引用
在**resources/assets/js/bootsrap.js** 中引入刚下载的资源包:

// 引入markdown编辑器 window.simplemde = require('simplemde');

### 1.3 编译静态资源
使用命令编译刚引入的资源,这样才可以编辑在**public/app.js**中:

npm run dev

OK,这样就引入到前端资源文件中了

Demo:


SimpleMDE Dome

<body>

    <h1>SimpleMDE Dome</h1>

    <div class="container">
        <textarea name="" rows="" cols="" id="editor"></textarea>
    </div>

    <script type="text/javascript">
        // Most options demonstrate the non-default behavior
        var simplemde = new SimpleMDE({
            autofocus: true,
            autosave: {
                enabled: true,
                uniqueId: "editor01",
                delay: 1000,
            },
            blockStyles: {
                bold: "__",
                italic: "_"
            },
            element: document.getElementById("editor"),
            forceSync: true,
            hideIcons: ["guide", "heading"],
            indentWithTabs: false,
            initialValue: "SimpleMDE Dome",
            insertTexts: {
                horizontalRule: ["", "\n\n-----\n\n"],
                image: ["![](http://", ")"],
                link: ["[", "](http://)"],
                table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text     | Text      | Text     |\n\n"],
            },
            lineWrapping: false,
            parsingConfig: {
                allowAtxHeaderWithoutSpace: true,
                strikethrough: false,
                underscoresBreakWords: true,
            },
            placeholder: "placeholder",
           /* previewRender: function(plainText) {
                console.log(plainText)
                return customMarkdownParser(plainText); // Returns HTML from a custom parser
            },
            previewRender: function(plainText, preview) { // Async method
                setTimeout(function(){
                    preview.innerHTML = customMarkdownParser(plainText);
                }, 250);

                return "Loading...";
            },*/
            promptURLs: true,
            renderingConfig: {
                singleLineBreaks: false,
                codeSyntaxHighlighting: true,
            },
            shortcuts: {
                drawTable: "Cmd-Alt-T"
            },
            showIcons: ["code", "table"],
            spellChecker: false,
            status: false,
            status: ["autosave", "lines", "words", "cursor"], // Optional usage
            status: ["autosave", "lines", "words", "cursor", {
                className: "keystrokes",
                defaultValue: function(el) {
                    this.keystrokes = 0;
                    el.innerHTML = "0 Keystrokes";
                },
                onUpdate: function(el) {
                    el.innerHTML = ++this.keystrokes + " Keystrokes";
                }
            }], // Another optional usage, with a custom status bar item that counts keystrokes
            styleSelectedText: false,
            tabSize: 4,
            //toolbar: flase,
            //toolbarTips: false,
        });
    </script>

</body>

``` ### 1.4 在Laravel-admin中集成Simplemde编辑器

我们可以给下边的laravel-admin后台 集成该 Markdown 的编辑器。 

Simplemde 是一个优秀简洁的Markdown编辑器,如果** laravel-admin** 自带的基于 ckeditor的编辑器组件使用上有问题,可以通过下面的步骤可以集成它,并覆盖掉ckeditor

1.4.1 先下载前端库文件Simplemde

先下载前端库文件Simplemde, 解压到目录public/packages/admin/simplemde

1.4.2 新建组件类

然后新建组件类app/Admin/Extensions/Simplemde.php

<?php

namespace App\Admin\Extensions;

use Encore\Admin\Form\Field;

class Simplemde extends Field
{
    protected $view = 'admin::form.editor';

    protected static $css = [
        '/packages/admin/simplemde/dist/simplemde.min.css',
    ];

    protected static $js = [
        '/packages/admin/simplemde/dist/simplemde.min.js',
    ];

    public function render()
    {
        $this->script = <<<EOT

 var simplemde = new SimpleMDE({
               autofocus: true,
                autosave: {
                    enabled: true,
                    delay: 5000,
                    unique_id: "editor01",
                },
                spellChecker: false,
            });

EOT;
        return parent::render();

    }
}

1.4.3 注册

然后注册进laravel-admin,在 app/Admin/bootstrap.php 中添加以下代码:

<?php

/**
 * Laravel-admin - admin builder based on Laravel.
 * @author z-song <https://github.com/z-song>
 *
 * Bootstraper for Admin.
 *
 * Here you can remove builtin form field:
 * Encore\Admin\Form::forget(['map', 'editor']);
 *
 * Or extend custom form field:
 * Encore\Admin\Form::extend('php', PHPEditor::class);
 *
 * Or require js and css assets:
 * Admin::css('/packages/prettydocs/css/styles.css');
 * Admin::js('/packages/prettydocs/js/main.js');
 *
 */

// Encore\Admin\Form::forget(['map', 'editor']);

use App\Admin\Extensions\Simplemde;
use Encore\Admin\Form;

Form::extend('editor', Simplemde::class);

1.4.4 使用

// 这样就可以使用我们上边自定义的Simplemde Markdown编辑器了
$form->editor('content');

完整文件

  /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        return Admin::form(Article::class, function (Form $form) {

            $form->display('id', 'ID');
            $form->text('title', '标题')->rules('required|min:3');
            $form->text('subtitle', '副标题');

            $form->text('user_id', '作者ID')->default(4);
            $form->text('slug', 'Slug')->default('My-blog-4');
            $form->text('category_id', '分类ID')->default(1);
            $form->text('order', '排序')->default(1);
            $form->radio('is_excellent', '是否精华')->options(['F' => '否', 'T' => '是'])->default('T');

            // 图片路径为upload/images/
            $form->image('page_image', '上传文章背景图')->move('images', function($file){

                // 自定义文件名,时间戳+五个随机字符串+用户ID
                $file_name =  date("Ymd") . str_random(6);
                return $file_name . "." . $file->guessExtension();
            });

            $form->datetime('published_at', '发布作品时间')->format('YYYY-MM-DD HH:mm:ss');

            $form->display('created_at', trans('admin::lang.created_at'));
            $form->display('updated_at', trans('admin::lang.updated_at'));

            // 自定义的编辑器
            $form->editor('content')->rules('required|min:3');
        });
    }

2.Markdown解析类


segmentfault 的Markdown解析类:SegmentFault/HyperDown

Laravel 引入第三方类文件,我们在app目录下新建一个路径,app/Markdown,并将下载的类文件 Parser.php 放在该目录下,然后再新建一个文件,引用该类,这样做的好处就是可以完全分离核心类文件,如同合约contacts 一样,如果以后我们的解析类变了,我们只需对核心类做改变,而其他应用的方法不需要再修改。

markdown.php 引用 parse.php 类:

<?php

namespace App\Markdown;

/**
 * Class Markdown
 *
 * @package \App\Markdown
 */
class Markdown
{
    protected $parser;

    /**
     * Markdown constructor.
     *
     * @param $parser
     */
    public function __construct(Parser $parser)
    {
        $this->parser = $parser;
    }

    public function markdown($text)
    {
        $html = $this->parser->makeHtml($text);

        return $html;
    }


}

在引用第三方类后,需要执行下面命令进行自动加载:

composer dump-autoload

使用方法:

<?php

protected $markdown;
public function __construct(Markdown $markdown)
{
   $this->markdown = $markdown;
}

// 解析Markdown 内容
$this->markdown->markdown($article->content);

3.Markdown语法高亮


Laravel 给highlight.js高亮插件 添加增加行数-点击

Laravel 给Markdow代码片添加高亮-点击这里

找了一个非常简洁的** Markdown** 样式文件,我放在了 *Gist *上,有需要的朋友可以看看: Gist: corwien/Markdown.scss

将该文件下载放在Laravel中 resources/assets/css/vendor/markdown.scss,然后在 resources/sass/app.scss中引入:

// Markdown

// 代码高亮
@import "./../css/vendor/highlight.min";

// 编辑器样式文件
@import "./../css/vendor/simplemde.min";

// 引入markdown样式文件
@import "./../css/vendor/markdown.scss";

然后编译前端资源文件:

npm run dev

这样,该markdwon样式文件就编译到前端资源文件中了。

我们可以在前端的内容字段处引入 class="markdown" 样式,然后看看渲染效果: article.blade.php

    <div class="markdown" >
       {!! $article->content !!}
    </div>

代码块是不是很简洁清爽许多呢?

八、开源的管理后台


我们可以在项目中引入开源的管理后台,这样可以大大的提高我们的项目开发速度,这里推荐两个非常强大的开源管理后台。

1.Laravel-Administrator


【扩展推荐】管理员后台快速生成工具 Administrator "增强版" 分享

项目GitHub地址:summerblue/administrator

该后台非常好用,由Laravel-China 团队维护开发,十分钟就可以搭建起一个简单的管理后台:

2.laravel-admin


该管理后台非常强大,使用Laravel AdminLTE开发,可以快速实现增删改查功能及角色管理。

项目:GitHub地址: z-song/laravel-admin

Demo: 后台用户名:admin 密码:admin

由于该前端资源有引入google地图,所以,前端加载会非常慢,这里我们对源码进行一下修改: 换掉谷歌的地图,加载时间过长: /vendor/encore/laravel-admin/src/Form/Field/Map.php

/**
     * Get assets required by this field.
     *
     * @return array
     */
    public static function getAssets()
    {
        // 本项目配置环境使用的语言包是zh-CN,'resources/lang/zh-CN/', 所以这里对zh_CN做出修改【20170501】
        if (config('app.locale') == 'zh-CN') {
            $js = 'http://map.qq.com/api/js?v=2.exp';
        } else {
            $js = 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&key='.env('GOOGLE_API_KEY');
        }

        return compact('js');
    }

九、Markdown侧边栏生成


为了使我们的文章详情页更利于浏览,像SF一样,有一个侧边导航栏,这里我们使用一段js代码就可以轻松的实现该功能。

js代码:

<link rel="stylesheet" href="http://yandex.st/highlightjs/6.2/styles/googlecode.min.css">

<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://yandex.st/highlightjs/6.2/highlight.min.js"></script>

<script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
 $(document).ready(function(){
      $("h2,h3,h4,h5,h6").each(function(i,item){
        var tag = $(item).get(0).localName;
        $(item).attr("id","wow"+i);
        $("#category").append('<a class="new'+tag+'" href="#wow'+i+'">'+$(this).text()+'</a></br>');
        $(".newh2").css("margin-left",0);
        $(".newh3").css("margin-left",20);
        $(".newh4").css("margin-left",40);
        $(".newh5").css("margin-left",60);
        $(".newh6").css("margin-left",80);
      });
 });
</script>
<div id="category"></div>


推荐