はじめに
Djangoでブログ機能を実装し、CKEditor4を使って記事を作成していますが、
見出しに付けたid属性が保存後に消えてしまう問題に遭遇しました。
例えば目次のアンカーリンクを作るために以下のように書いても、
<h3 id="section1">見出し</h3>
再度編集画面で開くと、
<h3>見出し</h3>
のように id属性だけが消えてしまう 状態になります。
目次
1. 発生した問題
CKEditorを使って記事を作成し、目次用のアンカーリンクを実装していました。
<a href="#section1">目次リンク</a> <h3 id="section1">1. 見出し</h3>
しかし保存後に再度編集画面を開くと、
- id属性が消える
- classが消える場合もある
結果として、目次リンクが機能しなくなりました。
2. 原因
原因は、CKEditorのHTMLフィルタ機能です。
CKEditorはセキュリティ対策として、以下のような動作を行います。
- 許可されていない属性を自動削除
- 危険なタグ(scriptなど)を削除
これはXSS(クロスサイトスクリプティング)対策のための仕様です。
参考(公式ドキュメント):
https://ckeditor.com/docs/
3. 解決方法
解決方法は、CKEditorの設定で「許可するHTML」を指定することです。CKEditorの設定はsettings.pyに記載します。
方法①:すべて許可
CKEDITOR_CONFIGS = {
'default': {
'allowedContent': True,
},
}
この設定により、HTMLの制限が解除されます。
idやclassもそのまま保存されるようになります。
方法②:必要なものだけ許可
CKEDITOR_CONFIGS = {
'default': {
'extraAllowedContent': 'h2[id]; h3[id]; a[class,href];',
},
}
この設定では以下を許可します:
- h2, h3 の id属性
- aタグの class, href
必要なものだけ許可するため、セキュリティ的にも安全です。
4. 消えるその他の属性
id以外にも、以下の属性が消えることがあります。
- class(CSS用)
- style(インラインCSS)
- data-* 属性
例えば:
<a href="#" class="btn btn-primary">ボタン</a>
これも設定次第では class が消えます。
そのため、Bootstrapなどを使う場合は特に注意が必要です。
必要に応じて以下のように追加します。
'extraAllowedContent': 'a[class,href];'
5. おわりに
ブログで目次リンクを使う場合、id属性は必須です。
同じ問題で悩んでいる方は、ぜひ設定を見直してみてください。
追記:CKEditor4はサポートが終了しているためCKEditor5を使うようにしましょう。