Laravel: There is a Markdown parser and you don’t know it

This is where Parsedown comes into play.

For convenience, we will register the Parsedown as a singleton service in our application, so we can automatically inject it wherever we want, using the appProvidersAppServiceProvider class.

It’s optional, so if you don’t use it anywhere, you can just instance it normally where you require it.

/** * Bootstrap any application services.

* * @return void */public function boot(){ $this->app->singleton(Parsedown::class); // .

}After that, let’s say in our Article model, we want to take out the Markdown text stored and retrieve it as HTML.

No problem, we can use an accessor in our Article Model.

/** * Get the Article's text as HTML * * @return IlluminateSupportHtmlString */public static function getTextAttribute($value){ return new HtmlString( app(Parsedown::class)->setSafeMode(true)->text($text) );}The important part here is the HtmlString class.

When Blade templates receives an object that implements the Htmlablea interface, like the simple HtmlString class, it will use the toHtml() method instead of parsing it as a string.

In this case, your view will receive a HtmlString and return the HTML generated by the Parsedown package, which is very simplistic.

Safe mode?Yeah, about that.

Parsedown comes with a flag called safeMode() that “sanitizes” the output HTML.

You can combine this with packages like Purifier to clean what comes out if you want to be 100% sure what is displayed doesn’t break your site, or doesn’t inject scripts.

Caching the parsingSince the parsing may take some precious computation time, it’s not bad to handle this using hashes and cache, specially when the text to parse is big.

This can be a very basic but useful way to not parse the text every time.

/** * Get the Article's text as HTML * * @return IlluminateSupportHtmlString */public function getTextAttribute($value){ // Hash the text with the lowest computational hasher available.

$key = 'article|'.

$this->id.

'|'.

hash(MHASH_ADLER32, $value); // If the cache with this hash exists, return it, otherwise // parse it again and save it into the cache for 1 day.

return Cache::remember($key, 86400, function () use ($value) { return $this->parseMarkdownToHtml($text); })}/** * Get the Article's text as HTML * * @return IlluminateSupportHtmlString */protected function parseMarkdownToHtml(string $text){ return new HtmlString(app(Parsedown::class)->text($text));}Of course you can expand on this, like saving the hash to a column in the database, and using that information to forget the old cache and put the new information.

And that’s it.

There is no need to install additional packages or create your own parser for your data.

.

. More details

Leave a Reply