投稿をマークダウンにする

2024/01/18に公開

parsedownとprism.jsをつかってzennにもあるようなエディタ風の投稿をできるようにする

parsedown

composer require erusev/parsedown

composerでインストールしたらPostsControllerのviewメソッドにparsedown用の記述をおこなう

PostsController.php
    /**
     * View method
     *
     * @param string|null $id Post id.
     * @return \Cake\Http\Response|null|void Renders view
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function view($id = null)
    {
        $post = $this->Posts->get($id, [
            'contain' => ['Categories', 'Tags', 'Comments'],
        ]);
		// parsedoenクラスをインスタンス化して使えるようにする
		$parsedown = new \Parsedown();
		$post->body = $parsedown->text($post->body);

		// Commentsテーブルから空のエンティティを作成。
		// フォームからデータを受けるために必要。
		$comment = $this->Posts->Comments->newEmptyEntity();

		// コメント保存用の処理。
		if ($this->request->is('post') && $this->request->getData('comment')) {
			$commentData = $this->request->getData('comment');
			$commentData['post_id'] = $id;
			$comment = $this->Posts->Comments->patchEntity($comment, $commentData);
			if ($this->Posts->Comments->save($comment)) {
				$this->Flash->success('新しいコメントが追加されました。');
				return $this->redirect(['action' => 'view', $id]);
			} else {
				$this->Flash->error('コメントを追加できませんでした。もう一度試してください。');
			}
		}

        $this->set(compact('post'));
    }

テンプレートに最初からあるエスケープを外す

view.php
// templates/Posts/view.php
<div class="text">
    <strong><?= __('Body') ?></strong>
    <blockquote>
	<!-- ここにh()で囲われている部分がある -->
        <?= $this->Text->autoParagraph($post->body); ?>
    </blockquote>
</div>

prism.js

https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript
公式サイトから必要なファイルをダウンロードする
そしたらwebrootディレクトリにあるcssとjsディレクトリに入れる

default.php
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         0.10.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 * @var \App\View\AppView $this
 */

$cakeDescription = 'CakePHP: the rapid development php framework';
?>
<!DOCTYPE html>
<html>
<head>
    <?= $this->Html->charset() ?>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>
        <?= $cakeDescription ?>:
        <?= $this->fetch('title') ?>
    </title>
    <?= $this->Html->meta('icon') ?>

    <?= $this->Html->css(['normalize.min', 'milligram.min', 'fonts', 'cake']) ?>
    <!-- cssファイル -->
    <?= $this->Html->css('prism-tomorrow.min.css') ?>

    <?= $this->fetch('meta') ?>
    <?= $this->fetch('css') ?>
    <?= $this->fetch('script') ?>
</head>
<body>
    <nav class="top-nav">
        <div class="top-nav-title">
            <a href="<?= $this->Url->build('/') ?>"><span>Cake</span>PHP</a>
        </div>
        <div class="top-nav-links">
            <a target="_blank" rel="noopener" href="https://book.cakephp.org/4/">Documentation</a>
            <a target="_blank" rel="noopener" href="https://api.cakephp.org/">API</a>
        </div>
    </nav>
    <main class="main">
        <div class="container">
            <?= $this->Flash->render() ?>
            <?= $this->fetch('content') ?>
        </div>
    </main>
    <footer>
    </footer>
    <!-- jsファイル -->
    <?= $this->Html->script('prism.js') ?>
</body>
</html>

これでOK
あとは投稿時にzennと同じようにバッククォート3つで囲んであげれば
エディタ風の見た目になる

Discussion