Creating markdown field type : Getting started

I definitely could use a field for a Markdown editor (I use it for this blog). So I decided to add one to the core of LaraManager.

View Project

I definitely could use a markdown editor field type in my Laravel admin tool Laramanager. So I decided to add one to the core. In a previous version of Laramanager, there was one. However, this was bundled into UIKit 2. The latest verion of LaraManager uses UIKit 3 which did not carry over the HTML/Markdown editor. So, I took a look at a few options for a new editor and parser and didn't find anything I liked that worked "out of the box". So, I decided to build my own with some really great existing JS packages.

I decided to try out CodeMirror (codemirror.net) for the editor. To get started I'll start by installing the codemirror node package in Laramanager.

npm install codemirror --save

Now I want to load the modes/languages for this package. Just for now, I'm going to load the main modes I will use. Maybe in the future I'll build a few options for accomidating more. But for now I'm just going to load JS, PHP, XML/HTML and GFM (Github Flavored Markdown) modes.

assets/js/scripts.js

window.codemirror = require('codemirror');
require('codemirror/mode/markdown/markdown');
require('codemirror/mode/gfm/gfm');
require('codemirror/mode/javascript/javascript');
require('codemirror/mode/php/php');
require('codemirror/mode/xml/xml');

Now I'm going to make a new field directory in the core fields in Laramanager.

src/views/fields/markdown

In this directory there are 4 files that are supported for any core field.

  • display.blade.php (Required) This view renders the value in the field on the admin side.
  • field.blade.php (Required) This view renders the form input(s) for the field.
  • scripts.blade.php Scripts required by the field
  • options.blade.php Generally fields are presented in this view when the field needs additional information.

I will need all but the options.blade.php view and will start with the field.blade.php view.

src/views/fields/markdown/field.blade.php

@include('laramanager::partials.elements.form.textarea', [
    'field' => [
        'name' => $field->slug,
        'class' => 'field-markdown',
        'value' => isset($entity) ? $entity->{$field->slug} : null
    ]
])

Notice that I am using a form helper built into the LaraManager core. Now I'll add it to the list of fields.

src/Philsquare/LaraManager/Http/Controllers/ResourceFieldController.php

class ResourceFieldController extends Controller {

    protected $fields = [
        'text' => 'Text',
        'email' => 'Email',
        'slug' => 'Slug',
        'password' => 'Password',
        'image' => 'Image',
        'images' => 'Images',
        'checkbox' => 'Checkbox',
        'textarea' => 'Textarea',
        'wysiwyg' => 'WYSIWYG',
        'select' => 'Select',
        'date' => 'Date',
        'relational' => 'Relational',
        'markdown' => 'Markdown'
//        'html' => 'HTML'
    ];

    ...

}

This controller will pass this list into the field create view which contains the field type dropdown list.

Ok, that is enough for me to start testing it out. But first, I need to create a new resource for testing this field in LaraManager. I'll do this by setting up a posts table with a text column called body, add a "Post" model and then add it as a resource (https://laramanager.philmareu.com/docs/resources).

Laramanager field type list dropdown

The field shows up in the list, so that's great. Let's see if this field type will get added as a field.

Laramanager field type list

Well, I was able to save the field to this resourse. Excellent. Now to try and use the editor when adding a new entry.

Laramanager markdown field type not initialized

It looks like a plain textarea field. This makes sense, I haven't initiated the editor. I'll need to add the appropriate JS to the script.blade.php view file to make this happen.

src/views/fields/markdown/scripts.blade.php

<script>
    _.forEach(document.getElementsByClassName('field-markdown'), function(field) {
        codemirror.fromTextArea(field, {
            mode: 'gfm',
            theme: "default",
            extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"}
        })
    });
</script>

Laramanager markdown field type initialized

After refreshing the page the field seems to be working! Looks like it could use a border and some other style adjustments. But I won't worry about that now.

One more thing, I need the display.blade.php view. This view is basically the preview of the content used by a few panels in the admin.

src/views/fields/markdown/display.blade.php

<div id="markdown-display-{{ $field->id }}">
    {!!  Parsedown::instance()->text($entity->{$field->slug}) !!}
</div>

Here I am using the PHP parser Laravel uses for parsing email templates. Super simple.

This is a good stopping point. In another post, I will add a full-screen mode and the ability to preview the markdown in rendered HTML.

2023 Phil Mareu - Coder, Traveler & Disc Thrower