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.

Legal stuff about this site and your private life:

  • We use a cookie to keep your preferences (language, NSFW status, login status) during navigation.
  • We use your local storage to save the announces you closed (like this one).
  • We don't save informations you don't give
  • We don't share your email address if you comment or register
  • There is no tracker of any kind.

If you're not OK with this, move your way.

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.