
Security News
Oxlint Introduces Type-Aware Linting Preview
Oxlint’s new preview brings type-aware linting powered by typescript-go, combining advanced TypeScript rules with native-speed performance.
coffee-views
Advanced tools
Coffee Views was inspired by coffee-templates and coffeekup to add template inheritance to CoffeeScript templating.
npm i --save coffee-views
# views/layout.coffee
{Html} = require 'coffee-views'
module.exports = class Layout extends Html
# The #render() method is automatically called when rendering the view in express.
render: (options)->
@doctype 5
@html {lang:'en'}, ->
@head ->
@title options.title
@stylesheetBlock()
@body ->
@h1 options.title
@contentBlock()
stylesheetBlock: ->
@link rel:'stylesheet', href:'/css/main.css'
contentBlock: ->
# views/myview.coffee
Layout = require './layout'
module.exports = class MyView extends Layout
contentBlock: ->
@div ->
@p 'This is my view'
View = require './views/myview'
view = new View()
console.log view.compile 'render', title: 'My Site'
... will produce ...
<!doctype html>
<html lang="en">
<head>
<title>My Site</title>
<link rel="stylesheet" href="/css/main.css"/>
</head>
<body>
<h1>My Site</h1>
<div>
<p>This is my view</p>
</div>
</body>
</html>
# app.coffee
# using the templates in the previous example
# ...
app = express()
app.configure ->
app.engine 'coffee', require('coffee-views').engine
app.set 'view engine', 'coffee'
app.set 'views', path.join(__dirname, 'views')
# ...
app.get '/', (req, res)->
res.render 'myview',
title: 'My Site'
Just use CoffeeScript's native super()
method to return a rendered parent method.
class MyExtendedView extends MyView
contentBlock: ->
super
@div ->
@p 'This is an extension to "MyView"'
view = new MyExtendedView()
console.log view.compile 'render', title: 'My extended view'
###
<!doctype html>
<html>
<head>
<title>My extended view</title>
</head>
<body>
<h1>My extended view</h1>
<div>
<p>This is my view</p>
</div>
<div>
<p>This is an extension to "MyView"</p>
</div>
</body>
</html>
###
There's a possibility you may want to use plain JavaScript instead of CoffeeScript. In this case, just use Node's util module to extend your classes:
// layout.js
var Html = require('coffee-views').Html,
util = require('util');
function Layout(){}
module.exports = Layout;
util.inherits(Layout, Html);
Layout.prototype.render = function(options){
this.doctype(5);
this.head(function(){
this.title(options.title);
this.stylesheetBlock();
});
this.body(function(){
this.h1(options.title);
this.contentBlock();
});
};
Layout.prototype.stylesheetBlock = function(){};
Layout.prototype.contentBlock = function(){};
// myview.js
var Layout = require('./layout'),
util = require('util');
function MyExtendedView(){}
module.exports = MyExtendedView;
util.inherits(MyExtendedView, Layout);
MyView.prototype.contentBlock = function(){
this.div(function(){
this.p('My content');
});
};
// extendedview.js
var MyView = require('./myview'),
util = require('util');
function ExtendedView(){}
module.exports = ExtendedView;
util.inherits(ExtendedView, MyView);
ExtendedView.prototype.contentBlock = function(){
ExtendedView.super_.prototype.contentBlock.call(this);
this.div(function(){
this.p('Native extensions');
});
};
When creating your own XML tags you can register them like so:
# my-xml.coffee
{Xml} = require 'coffee-views'
class MyXml extends Xml
MyXml.registerTag 'mung'
MyXml.registerTag 'face'
MyXml.registerOpenTag 'this-is-always-open'
MyXml.registerClosedTag 'this-is-always-closed'
# your-xml.coffee
MyXml = require './my-xml'
class YourXml extends MyXml
render: ->
@mung ->
@face 'yay, custom tags'
@['this-is-always-open']()
@['this-is-always-closed']()
# <mung><face>yay custom tags</face></mung>
# <this-is-always-open></this-is-always-open>
# <this-is-always-closed/>
Apart from the obvious HTML5 compliant tags, here are a few extras.
Using the #javascript()
function will create a <script>
tag with the passed function as a string.
class MyView extends Html
javascriptBlock: ->
@javascript ->
alert 'Yay! CoffeeScript'
view = new MyView()
console.log view.compile 'javascriptBlock'
###
<script>
(function () {
alert('Yay! CoffeeScript!');
}).call(this)
</script>
###
You can also pass server variables through to your client code:
class MyView extends Html
javascriptBlock: (options)->
# Assuming "options" is {username:'Craig David'}
@javascript [options.username], (username)->
alert "Your name is #{username}. Lucky you. *snigger*"
@javascript [options], (options)->
alert "Name: #{options.name}"
@javascript [-> 'Craig David'], (getName)->
alert "getting name... #{getName()}"
... will produce ...
<script>
(function(username){
alert('Your name is ' + username + '. Lucky you. *snigger*');
}).call(this, 'Craig David')
</script>
<script>
(function(options){
alert('Name: ' + options.name);
}).call(this, {username:'Craig David'});
</script>
<script>
(function(getName){
alert('getting name... ' + getName());
}).call(this, function(){ return 'Craig David'; })
</script>
The #css()
method renders as CCSS. Pass an object and it will create a <style>
tag.
class MyView extends Html
stylesheetBlock: ->
@css
form:
input:
padding: '5px'
border: '1px solid'
view = new MyView()
console.log view.compile 'stylesheetBlock'
###
<style>form input {
padding: 5px;
border: 1px solid;
}
</style>
###
Using the #lit()
method will just add any content to the output string:
class MyView extends Html
contentBlock: ->
@lit '<wierdtag/> Mung'
view = new MyView()
console.log view.compile 'contentBlock'
###
<wierdtag/> Mung
###
Using the #unlit()
method will escape content if #safeOutput is set to true (which it is by default).
class MyView extends Html
contentBlock: ->
@unlit '<wierdtag/> Mung'
view = new MyView()
console.log view.compile 'contentBlock'
###
<wierdtag/> Mung
###
If you want to make sure something is escaped, go ahead and use the #escape() method:
escapedContent = @escape '<mung>' # => '<mung>'
HTML comments.
@comment 'Here\'a a comment'
@comment ->
@p 'I\'ve been a commented out'
@ie ->
@link rel:'stylesheet', href:'ie.css'
@ie 7, ->
@link rel:'stylesheet', href:'ie7.css'
FAQs
An OOP extension to coffee-templates
The npm package coffee-views receives a total of 17 weekly downloads. As such, coffee-views popularity was classified as not popular.
We found that coffee-views demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oxlint’s new preview brings type-aware linting powered by typescript-go, combining advanced TypeScript rules with native-speed performance.
Security News
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
Security News
Astral unveils pyx, a Python-native package registry in beta, designed to speed installs, enhance security, and integrate deeply with uv.