Simple Angular Blog Engine :: Part 1

I know. I know. There are so many blog engines out there. I just can’t help myself. Even if you are not creating a blog — you might be interested in using a Markdown Editor in your Angular applications.

  • Part I: Angular Module with Markdown Editor Component
  • Part 2: Creating Blog Post
  • Part 3: Display Blog Posts
  • Part 4: Refactor to Shared Angular Library

And still, I want to create yet another one. I already have the back end of the application generated/complete using my code generator/scaffolding tool. This tool creates the Web API, services, business layer with business rules, repository for data access, and Entity Framework data access components. So, really my main effort will be the Angular front end — still a lot of work.

The real motivation is to create an Angular client for the blog using a shared Angular library. I also want to be able to reuse the markdown content as source for some guides and ebooks.

Here are some of my top requirements:

  • Work with the latest version of Angular.
  • Be available from npm.
  • The editor and source of the blog must support markdown. I want to leverage the markdown files for my bookdown projects. See: https://bookdown.org/yihui/bookdown/
  • The content of the blog posts will be stored as bytes with an indicator as to the source type (i.e., markdown, HTML, or text).
  • The application will parse (process) the markdown and create HTML output for the blog display.
  • Work with the Web API Content microservice; and other microservices to support the blog engine.
  • The blog will be an Angular Module library with: Administrative Features (Services and Components), Domain Service, Components, and Directives

The Markdown Editor

After some initial research I selected https://www.npmjs.com/package/simplemde. It has a nice set of features and configurable options. Later, I’ll refactor the implementation to a custom Angular @NgModule as a shared Angular Library — it will allow consumers of the module to provide the configuration to the markdown editor component using the conventional forRoot(..) static method of the module. The simplemde npm package already has several options defined as interfaces. Therefore, it will be easy to set the editor options at runtime.

Let’s get started.

Package Installation

Retrieve the simplemde package from npm.

npm install simplemde -S

You will also need the types later,

npm install -S @types/simplemde@1.11.6

Styles and Script Configuration

Add the following to the angular-cli.json file in the styles section of the apps node.

"../node_modules/simplemde/dist/simplemde.min.css"

Add the following to the angular-cli.json file in the scripts section of the apps node.

"../node_modules/simplemde/dist/simplemde.min.js"

Create an Application Module

Create a module for the editor.

ng generate module modules\markdownEditor

Add a new component to the editor.

ng generate component modules\markdownEditor\editor

Update the MarkdownEditorModule to export the component.

Editor Configuration

The editor has a nice set of Options defined for the configuration. Our implementation is using an Angular module. This will allow us to setup a forRoot static method to pass along the configuration using the defined interface already provided by simplemde.

Update Module for Configuration

First thing to do is to create a class that will contain the options using the interface provided by the editor. We will use this class to pass in the configuration when the module is initialized by the application.

Notice that we need to import the SimpleMDE class so that we can reference the Options interface for implementation. Notice that all of the members of the interface are nullable. Additionally, they are all strongly typed - this is a good thing, right?

To allow the module to accept the configuration when it is initialized, we will create a static method using the Angularconvention: forRoot(..). Import the MarkdownEditorOptions options and implement the forRoot static method. This will provide or make available the configuration to the module members at runtime. What we want is the component to be able to use the configuration to initialize an editor instance with the configuration.

Reference the MarkdownEditorModule

The application where I’m using this module uses a Core module to contain references to modules used by my Angular application. Reference the required items in your CoreModule or AppModule whichever makes sense for your application.

import { MarkdownEditorModule } from './../markdown-editor/markdown-editor.module';
import { MarkdownEditorOptions } from './../markdown-editor/markdownEditorOptions';

Update the @NgModule imports to call the forRoot method on the MarkdownEditorModule - this allows us to pass in the configuration for the module.

MarkdownEditorModule.forRoot(editorConfig)

We’ll need to create a editorConfig instance so that we can pass it in. I'm pretty sure that just initializing a newMarkdownEditorOptions will not work. We'll probably need to create the instance using the same shape as the MarkdownEditorOptions class. If all goes well, when we use the editor the default content/value will be Hello Editor...write something amazing..

const editorConfig = new MarkdownEditorOptions();
editorConfig.autoDownloadFontAwesome = true;
editorConfig.initialValue = 'Hello Editor...write something amazing.';

Here is the code for the @NgModule that will import and provide the configuration to the MarkdownEditorModule.

Editor Component

It is really amazing that the HTML <textarea> element with a lot of JavaScript creates the markdown editor.

Here is the code for the EditorComponent. The constructor is looking for a MarkdownEditorOptions parameter. Since, this is injected using the the forRoot of the module during module loading - Angular will use dependency injection and provide the configuration setup in the CoreModule. The object is verified in the initializeEditor() method.

The parent component uses the @Input markdown to provide the child editor component the actual markdown content to display. This allows the editor component to be reused because its only responsibility is to display the content. The @Ouput EventEmitter provides any changes to the content to the parent component — the parent component will always have the current value of the markdown content.

Using the Markdown Editor Module

Create a component in your Angular application to use the markdown editor component from the MarkdownEditorModule.

The template of your component will need the selector for the editor component. Add the following to your HTML template.

<simplemde body [markdown]="postContent" (markdownChange)="onMarkdownChange($event)"></simplemde>
  • [markdown]: is the @Input to allow the parent component to provide the content using the postContent field.
  • (markdownChange): is the @Output implemented as an EventEmitter to allow the parent to be notified when the value changes. It is handled by the onMarkdownChange() method.

Concluding Part 1

I now have the beginnings of my blog engine. The most important requirement is the support for Markdown. I have a working module with configuration using Angular’s Dependency Injection, a component that takes input and emits markdown content changes to the parent component.

It is good for now. For more information about matt vaughn and the Angularlicious Podcast go to http://angularlicio.us.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store