vengeance

For modules, binding, and awesomeness with Pug.js as the backbone.

Usage no npm install needed!

<script type="module">
  import vengeance from 'https://cdn.skypack.dev/vengeance';
</script>

README

Vengeance

What drives some mad may be overcome with Vengeance.

Experimental!

Right now, I am experimenting with Vengeance. I am plotting a templating engine that will not only be an excellent, modular, server-side templating engine, but also a fully bound frontend framework. Ultimately, I seek to have a visual editor for styling, binding, editing modules, defining observable data, and validation geared toward serverless frameworks and a module ecosystem. But, seeking Vengeance takes time and patience so we'll see what happens.

Seeking Vengeance - Goals

  • Reusable modules
  • Uses Pug.js templating
  • Modules made up of single-file markdown documents for easy sharing (with Gist) and distribution
  • Modules can be used within modules
  • A system for module dependencies
  • Sass/CSS Compiling
  • CSS Sourcemaps
  • Concat CSS into single file
  • Concat client-side JavaScript into single file
  • Variables used for templating tracked for integration with a front-end binding framework
  • Font-end binding (in progress)
  • Visual editor powered by Vengeance for building Vengeance pages
  • Data/model designer with robust validation engine
  • Option for inlining content/styles/scripts (especially for above-the-fold content)

Install

npm install --save vengeance

Using

const pug = require('pug');
const withVengeance = require('vengeance');

const pug_settings = { /* normal Pug.js settings */ };
const vengeance_settings = { /* see below */ };

//...

pug.renderFile('index.pug', withVengeance(pug_settings, vengeance_settings));

How it will work

The plan is to have pretty normal looking Pug files with support for inheritance. However, if there are tags that look like m.namespace.module-name, Vengeance will go to the modules/namespace folder and load module-name.md. The markdown document will be parsed for the module template. That template will be parsed with Pug and swapped into the main file's AST. An example of this would be:

main.pug
!doctype html
html(lang="en")
  head
    title Greeting Page - Vengeance Demo
  body
    m.vengeance-demo.greeting
modules/vengeance-demo/greeting.md
# Demo Greeting Module

This module is used to display a simple greeting to the user.

## Template
```jade
h1 Hello User!
```

Once run, the main.pug will be rendered as if it was written like:

!doctype html
html(lang="en")
  head
    title Greeting Page - Vengeance Demo
  body
    h1 Hello User!

Module Arguments

The next step is accepting arguments for the module:

main.pug
//...
body
  m.vengeance-demo.greeting(greeting="Hello World!")
modules/vengeance-demo/greeting.md
# Demo Greeting Module

This module accepts a simple greeting to display to the user.

## Template
```jade
h1= $.greeting
```

The $.greeting part will be swapped with the "Hello world" value so now main.pug will be rendered as if it was written like:

!doctype html
html(lang="en")
  head
    title Greeting Page - Vengeance Demo
  body
    h1= "Hello World!"

About Swap Vars

The $.greeting you saw above is what I call a "swap var" because I'm litterally replacing the $.greeting text with the attribute value (in this case, `"Hello World"). So, if your module template looked like:

h1= $.customer.first_name

... and the module was used like:

m.vengeance-demo.greeting(customer=session.user)

... the result would be:

h1= session.user.first_name

Note that only the first part is swapped out.

In the future, I may get rid of the need for the $. syntax, I haven't decided. It helps differentiate between globals (ex: Math, Date, etc.) but I believe I will enforce all variables be declared in the attributes section of the module and eliminate the need for the $. prefix.

Vengeace should be able to handle complex swapping like:

// source
m.vengeance-demo.greeting(name= customer.first_name + ' ' + customer.last_name)

// module
h1= $.name.toUpperCase()

// rendered like
.result= (customer.first_name + ' ' + customer.last_name).toUpperCase()

and

// source
m.vengeance-demo.greeting(customers=store.customers vip=6)

// module
h1= $.customers[$.vip].first_name

// rendered like
h1= store.customers[6].first_name

Module Sections

Because the module is a markdown document, it can have several sections (h2 headlines). All the content before the first h2 will be used as the description of the module. After that, the following sections can be used (only the template section is required):

  • Attributes (coming soon!) - The module settings that can be changed and their types.
  • Defaults - Holds a JSON object that can be used to set the default values for the module. I hope to merge this into the Attributes section.
  • Style - Global css/sass for the module can be compiled into single file.
  • Scripts (coming soon!) - client-side scripts to be added to the page.
  • Template - required - Pug template for the module.

Module Sections - Attributes

This section will be for defining the module settings users can change. It should be a full tree of attributes with defaults, types, and descriptions of each attribute. By requiring this, we have a lot of information to use for building WYSIWYG editors to use and build interfaces with.

Spec

coming soon!

Module Sections - Defaults

Defaults is a section for defining the default value (in JSON) to be used for module swap vars. This is probably going to be merged into attributes later.

Spec

# A checkbox

## Defaults
```json
{
  "checked":false
}
```

## Template
```jade
input(value=$.value checked=$.checked)
```

Could be used like:

m.vengeance-demo.checkbox(value="newsletter" checked=true)
//- or (checked will be false)
m.vengeance-demo.checkbox(value="newsletter")

Module Sections - Style

Style section can be used to add Sass/CSS to the page when the module is included. The styles will be merged into a single file that can be included on the site. When merged, sourcemaps will be generated to allow debugging of styles.

Spec

# A Sass Module!

## Style

The following Sass will change the body background to black and all links to red:
```scss
$background-color: #000;
$link-color: #A00;

body {
    background: $background-color;
    
    a {
        color: $link-color;
    }
}
```

Module Sections - Template

This section you should be familiar with by now. It's simply a markdown codeblock with Pug markup

Spec

# Simple Template

## Template
```jade
| Hello world!
```