This website is based on the upcoming changes of the elabs Rails engine. Everything's not fine, but you can see the changes coming in the next releases.

I was working on a project and needed to create some documentation for the CSS used in the app. I created a custom directive to render the content of a VueJS component in plain text (template only).

Output

Requirements : vue, of course; clean-html, a library that cleans and reformat HTML strings and highlight.js to add some syntax highlight. As they are only needed during development, they are saved in the dev-dependencies:

npm install clean-html hightlight.js --save-dev

Here is the code I used to create this:

src/main.js

(or any file which is your entry point to your app):

//... other imports
import VueHighlighter from './highlighter';

Vue.use(VueHighlighter);

//... other vue conf

src/highlighter/index.js

import Vue from 'vue';
import hljs from 'highlight.js';
import cleaner from 'clean-html';

export default Vue.directive('block-to-code', {
  bind: (el, { value }) => {
    const options = value || {};
    let text = '';
    // As the string is a one-liner, we use the clean-html lib to clean it.
    // It outputs something like 'tidy'.
    cleaner.clean(el.innerHTML.toString(), options, (html) => {
      text = html;
    });

    // We replace the child content
    el.innerHTML = '';
    el.innerText = text;
    // Here we add the 'html' class to the element, so its content
    // will be highlighted as html.
    el.className += ' html';

    hljs.highlightBlock(el);
  },
  // Not done yet
  //componentUpdated: function componentUpdated(el, binding) {},
});

Usage: SomePage.vue

<template>
  <div class="content">
    <!-- rendered component -->
    <your-custom-component class="some-class"></your-custom-component>
    <!-- component source with the v-block-to-code directive -->
    <your-custom-component v-block-to-code></your-custom-component>
  </div>
</template>

And you can use the clean-html options:

<template>
  <div class="content">
    <!-- rendered component -->
    <your-custom-component class="some-class"></your-custom-component>
    <!-- component source with the v-block-to-code directive -->
    <your-custom-component v-block-to-code="{option1: val1}"></your-custom-component>
  </div>
</template>

Don't forget to load the hihlight.js theme you want to use...

Special thanks to Christoph Wiechert (@psi-4ward) for the idea of the directive.

Edit : Added options support (see clean-html docs for the list).

Leave a comment

You want to react to this content or ask something to the author? Just leave a comment here!

Note that the comments are not publicly visible, so don't worry if you don't see yours.

All the information you give will only be visible to the author. We don't share anything with anyone.

Don't fill this field if you want this form to be saved.