pencil

Custom tags/components for Jade. Extend, mixin and inherit.

npm install pencil
7 downloads in the last week
30 downloads in the last month

Stage
Build Status

version 0.1.4 (testing) - History

Pencil

Are you working with Jade? Do you want to make custom tags? Pencil is built on top of Jade to add extra features:

  • Create custom tags
  • Use jquery like functions to manipulate tags
  • Bootstrap support (not yet)
  • Extends Jade's include and extends

Installation

Install this using npm as follows

$ npm install pencil

Quick Start

Use default http server

var http = require('http')
  , fs = require('fs')
  , pencil = require('pencil')
  ;

http.createServer(function (req, res) {

  var path = __dirname + '/text.jade'
    , str = fs.readFileSync(path, 'utf8')
    , fn = pencil.compile(str, { filename: path, pretty: true })
    ; 

  res.writeHead(200, { 'Content-Type': 'text/html' });
  res.end(fn({}));

}).listen(3000);

Use Express

Supports Express 2.x and 3.x

var express = require('express')
  , pencil = require('pencil')
  ;

var app = express.createServer();

app.configure(function(){
  app.use(pencil.adapter.express(express, app));
});

app.get('/', function(req, res, next){
  res.render('text.jade', {
    layout: false
  });
});

app.listen(3000);

Pencil configures your Express server with defaults:

  • *.jade files are associated to the Jade parser
  • views are located in the ./view folder of your project

To use your own configuration:

app.use(pencil.adapter.express(express, app, {
  views: '/path/to/my/views'  // optional
}));

Extended html tags

Pencil extends a few html tags to have default attributes.

html
// <html lang='en'></html>
favicon
// <link href='/favicon.ico' type='image/x-icon' rel='shortcut icon' />

favicon(href='/image.ico')
// <link href='/image.ico' type='image/x-icon' rel='shortcut icon' />
head
  style(href='/style.css')
// <head>
//   <link href='/style.css' type='text/css' rel='stylesheet' />
// </head>

style
// <style type='text/css'></style>
script
// <script type="text/javascript"></script>

script(src='/script_path')
// <script type="text/javascript" scr="/script_path"></script>
form(action='/action_path')
// <form type='post' action='/action_path'>
//   <input type='hidden' name='_method' value='post' />
// </form>

form(method='put',action='/action_path')
// <form type='post' action='/action_path'>
//   <input type='hidden' name='_method' value='put' />
// </form>

// Alias
form:get
form:post
form:put
form:del
input
// <input type="text" />

// Alias
input:button
input:checkbox
input:file
input:hidden
input:image
input:password
input:radio
input:reset
input:submit
input:text
button
// <button type="button"></button>

// Alias
button:submit
button:reset

Custom tags

FROM NOW ON THE DOCUMENTATION IS NOT READY YET

The main purpose of Pencil is to build custom tags. Using Bike this comes very easy.

/example.jade

foo:box
// <div class='box'>Title Undefined</div>

foo:box(title='This is a box')
// <div class='box'>This is a box</div>

/foo/box.js

var Pencil = require('pencil');

Pencil.define('foo.box', {

  initialize: function(){
    var self = this
      ;

    this.tag
      .tag('div')
      .addClass('box')
      .html(this.title || 'Title Undefined')
    ;
  },

  render: function(){
    return this;
  }

});

How to

First you need to define a namespace.

Pencil.ns(__dirname + '/foodir');

The above code will look in the given directory for a file named namespace.json, the configuration of your namespace.

Attributes of the json file are:

  • name: [string] tells Jade's syntax to search any tag starting with the prefix name:* in the /foodir directory.
  • nameAlias: [string] alias for the name
  • alias: [object] key/value of alias for your custom tags used as shortcuts
foo:panel(title='Hello World')

This for examples searches the file /foodir/panel.js.

Optionally you could set your namespace as default to avoid the use of the prefix

Pencil.ns(__dirname + '/foodir', true);

Now you could do this:

panel(title='Hello World')

Every given attribute will be passed to the custom tag object.

Additionals elements in the tag name will be considered as subdirectories

foo:container:panel:header
=> /foodir/container/panel/header.js

Make one

/foodir/container.js

var Pencil = require('pencil');

Pencil.define('foo.container', {

  initialize: function(){
    var me = this;

    this.tag
      .tag('div')
      .html('Hello World')
  },

  render: function(){
    return this;
  }

});

Now inside your control you have the variable this.tag, this is the Jade Tag Object that you can manipulate as you like with the below functions (Extended Tag Object)

foo:container
=> <div>Hello World</div>

Since Pencil uses Bike it very easy to extend your custom controls

/foodir/panel.js

var Pencil = require('pencil');

Pencil.define('foo.panel', {

  extend: 'foo.container',

  initialize: function(){
    this._super.apply(this, arguments);

    this.tag.addClass('panel');
  }

});
foo:panel
=> <div class='panel'>Hello World</div>

For working and complex examples take a look at the /namespaces folder.

Extended Tag object

Jade's Tag object is extended with more methods to manipulate it in a jQuery like style.

This is very usefull when building custom controls or filters

  • isTag
  • sanitize
  • getName
  • tag
  • is
  • attr
  • getAttr
  • setAttr
  • removeAttr
  • attrToObj
  • css
  • addClass
  • removeClass
  • toggleClass
  • hasClass
  • append
  • appendTo
  • clone (*)
  • remove
  • prepend
  • prependTo
  • insertAfter
  • insertAfterTo
  • insertBefore
  • insertBeforeTo
  • show
  • hide
  • replaceWith
  • hasChilden
  • children
  • empty
  • clear
  • html
  • wrap
  • unwrap
  • wrapAll
  • wrapInner

Default extends

  • include
  • extends

If you set the variable Pencil.root with a path this will be helpful when using include and extends.

Pencil.root = '/root';

With Pencil your could include an external navbar.jade like this;

include user/navabar@repos/hello

The above code will try to include the file /root/repos/hello/view/user/navbar.jade.

The same works for extends

Running Tests

Install dev dependencies and make tests:

$ npm install -d
$ make test

Contributors

Gabriele Di Stefano <gabriele.ds@gmail.com>

Behere Logo

License

The MIT License

npm loves you