Markdown is a plain text format for writing structured documents, based on formatting conventions from email and usenet. On the other hand, front matter in the article's context is simply YAML's front matter block which I can assume, was inspired by the same word as used in book design.
Example from the following block,
---
title: Outline title
description: The shortest description ever written.
---
we can obtain the following object:
{
title: 'Outline title',
description: 'The shortest description ever written'
}
We'll be using the front-matter npm module to achieve this.
The inspiration for this tutorial is DEV.to's basic markdown editor that pushed me to create one for my own website.
Using front matter in the editor is a sound concept since it is better to have all article meta-data such as title, tags, description etc within the article content area than having a form with several input fields.
Creating The Editor
What we want is for our editor to take the combination of front-matter data and markup, then be able to extract the two before storing that data separately somewhere. We'll be using the front-matter module to extract the data we need from the text editor content.
Since we'll be working with markdown and front-matter in our editor, we'll add the two npm modules first.
$ npm i front-matter marked
Note: marked provides the following warning "Marked does not sanitize the output HTML. Please use a sanitize library, like DOMPurify (recommended), sanitize-html or insane on the output HTML!"
UIKit's css framework has been used to create the template for the editor as you'll notice from the CSS classes but feel free to style the editor to your liking.
The Template
<div id="editor-form-container" class="uk-margin">
<div id="button-container">
<button @click.prevent="previewMarkdown = !previewMarkdown" class="uk-button uk-button-primary uk-float-left">{{previewMarkdown ? "Edit Article" : "Preview Article"}}</button>
</div>
<div id="editor-container">
<textarea v-if="!previewMarkdown" id="d1" v-model="allContent" class="uk-textarea editor"></textarea>
<div v-else class="preview" v-html="compiledMarkdown"></div>
</div>
</div>
The Javascript
import Marked from 'marked'
import FrontMatter from 'front-matter'
export default {
name: "MarkdownEditor",
...
Our Variables
...
data(){
return {
previewMarkdown: false,
startContent: `---
title:
short_description:
tags:
post_image:
publish: false
---
Write content here
`,
allContent:"",
articleData: "",
},
},
...
previewMarkdown: A bool value that toggles the text of our button showing when we are editing or previewing the article.
startContent: What the text editor contains when the text editor is mounted.
allContent: All of the contents of the text editor at a given time.
...
computed:{
compiledMarkdown(){
let data = FrontMatter(this.allContent)
return Marked(data.body)
},
},
...
The compiledMarkdown computed value returns the processed html from the markdown within allContent which we preview within the block with v-html on the template above.
When the component has been mounted we assign the startContent to the allContent variable.
...
mounted(){
this.allContent = this.startContent
},
...
With the above code we can edit and preview our article. To get the variables passed in the front-matter block we'll add a getVariables() function and call it when needed.
...
methods: {
getVariables(){
const {body, attributes} = FrontMatter(this.allContent)
$nextTick(()=>{
articleData = {
content: body,
title: attributes.title,
description: attributes.short_description,
tags: attributes.tags,
image: attributes.post_image,
publish: attributes.publish,
}
})
// Then proceed to using articleData object as needed
}
},
...
This is just a starting point to this markdown editor. More features can be added to it such as text persistence with the help of vuex and the vuex-persistedstate plugin and more.
Top comments (0)