LoginSignup
8
7

More than 5 years have passed since last update.

laravel-adminのeditorにhtmlタグを許容させる

Posted at

背景

laravel-adminでhtmlページを入稿する機能を作ることってよくある(?)と思うのですが、
標準で利用できるeditorのCKEditorだと、htmlタグがエスケープされてしまう。

その結果思った通りの入稿ができない

その対策について

環境

  • laravel 5.5
  • php 7.1
  • laravel-admin 1.5.14

どういうことか?

フレームワークにのっとってformを作成する際に

$form->editor

って記述しておくと、laravel-adminが用意してくれているeditor(CKEditor)がformとして以下のように表示されるのですが、

スクリーンショット 2018-11-08 15.32.25.png

これにhtmlタグ入力すると自動でエスケープされます。

<strong>トピックス</strong>

って入力してpostすると

&lt;strong&gt;トピックス&lt;/strong&gt;

ってデータがエスケープされてまう・・・。

対処方法

標準だとform描画の際には以下のクラスのrenderが呼ばれるのですが、

Editor.php
<?php

namespace Encore\Admin\Form\Field;

use Encore\Admin\Form\Field;

class Editor extends Field
{
    protected static $js = [
        '//cdn.ckeditor.com/4.5.10/standard/ckeditor.js',
    ];

    public function render()
    {
        $this->script = "CKEDITOR.replace('{$this->column}');";

        return parent::render();
    }
}

な感じでレンダリングの際にCKEDITORに差し替えているのですが、
このCKeditorでは当然様々なconfigを設定することが可能でして

  CKEDITOR.replace('{$this->column}', {
    allowedContent: true,    // クラスの記述を許容するか
    basicEntities: false,    // 自動エスケープオフ
    entities : false         // 自動エスケープオフ(これも)
  });

な感じでreplaceの際に第二引数にconfigを渡すことができます。
(ざっくりした説明なので詳しいオプションの意味は公式で確認して見てください)

HtmlEditor.php

namespace App\Admin\Extensions\Widgets;

use Encore\Admin\Form\Field;

class HtmlEditor extends Field
{
    /**
     * @var string
     */
    protected $view = 'admin::form.editor';

    /**
     * @var array
     */
    protected static $js = [
        '//cdn.ckeditor.com/4.5.10/standard/ckeditor.js',
    ];

    /**
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function render()
    {
        $this->script = "
            CKEDITOR.replace('{$this->column}', {
                allowedContent: true,
                basicEntities: false,
                entities : false
            });
        ";

        return parent::render();
    }
}

で、app/Admin/bootstrap.phpから、上で作成したクラスを使うように指示する

bootstrap.php
use App\Admin\Extensions\Widgets\HtmlEditor;

// form->editorの対応クラスを上書き
Encore\Admin\Form::extend('editor', HtmlEditor::class);

これでformからの入力がエスケープされずにパスされるようになったぞ。
(逆いうとエスケープされないので気をつけてね)

補足

なんでプロパティのviewを設定しているの?

設定しないとフレームワークさんがおそらくクラス名からhtmleditorというviewを探そうとして死ぬからです。
今回は既存のeditorをそのまま使うので意図的に明言しておきます。

継承しません

Editorを継承した方が綺麗だったんですが、そうするとrender()で設定したconfigが上書きされてしまいます。
で、vendorのファイルには手を入れたくないので継承はやりません。

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7