In this presentation, I will use NodeJS, Express, Jade, coffee-script, and Twitter's Bootstrap to construct a simple list report generator that page breaks on every item. We will pretend that the SharePoint 2010 data is a custom list with three required columns and two optional columns that may not contain data: Title (string), Content (rich text), and Feedback (rich text), TextArea1, TextArea2. The last two are obviously the optional columns.
Imagine that this custom list contains a lot of text in each column. Viewing this in SharePoint would show it as a grid, with each associated property listed horizontally (think spreadsheet). There would be much scrolling or resizing of the browser. Why cant we view this data like a book or a white paper? That is what I intend to accomplish in this presentation.
First of all, you'll need to pick up all the tools. I am using Node 0.8.3 with the following modules: Express (3.0.0beta7), Jade (0.27.0), coffee-script (1.3.3), and request (2.9.203). All of the modules are on npm. See here for instructions on running coffee-script from the command line.
Next, pick up the latest bootstrap and its javascript plugins. Finally go get jQuery.
$ mkdir reportGenerator
$ cd reportGenerator
$ mkdir public routes views
Now that we have our public folder, lets put the client side stuff in there.
$ mv ~/Downloads/bootstrap ./public
$ mv ~/Downloads/jQuery.min.js ./public/bootstrap/js
Lets setup our web server.
$ vim app.coffee
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
express = require 'express' | |
routes = require './routes' | |
http = require 'http' | |
app = express() | |
app.configure ()-> | |
app.set 'port', (process.env.PORT or 3000) | |
app.set 'views', __dirname + '/views' | |
app.set 'view engine', 'jade' | |
app.use express.favicon() | |
app.use express.logger 'dev' | |
app.use express.bodyParser() | |
app.use express.methodOverride() | |
app.use express.cookieParser 'i sometimes like shrimp' | |
app.use express.session() | |
app.use app.router | |
app.use express.static __dirname + '/public' | |
app.configure 'development', ()-> | |
app.use express.errorHandler() | |
app.get '/', routes.index | |
http.createServer(app).listen app.get('port'), ()-> | |
console.log "Express server listening on port " + app.get('port') |
Now we need to create the route app.coffee depends on.
$ vim ./routes/index.coffee
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'coffee-script' | |
request = require 'request' | |
data = | |
getData: (cb)-> | |
username = 'someUser' | |
password = 'somePassword' | |
proto = 'https://' | |
site = 'sharepoint.domain.com/_vti_bin/listdata.svc' | |
config = | |
url: proto + username + ':' + password + '@' + site + '/' + 'someList?$orderby=someColumn' | |
json: true | |
request config, (err, res, body)-> | |
if err | |
console.log err | |
cb body.d.results | |
routes = | |
index: (req, res)-> | |
data.getData (dataArray)-> | |
options = | |
title: 'reportGenerator' | |
layout: 'layout.jade' | |
items: dataArray | |
res.render 'index', options | |
module.exports = routes |
Cool. So this route renders a Jade template. Lets make the layout and index templates.
$ vim ./views/layout.jade
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
doctype 5 | |
html | |
head | |
title= title | |
link(rel='stylesheet', href='/bootstrap/css/bootstrap.min.css') | |
script(src='/bootstrap/js/jquery-1.7.2.min.js', type='text/javascript') | |
script(src='/bootstrap/js/bootstrap.min.js', type='text/javascript') | |
body | |
block content |
$ vim ./views/index.jade
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends layout | |
block content | |
for item in items | |
.container-fluid(style='page-break-after:always') | |
.well | |
.row-fluid | |
h2 #{item.Title} | |
hr | |
h5 Content: | |
p | |
!= item.Content | |
hr | |
h5 Feedback: | |
p | |
!= item.Feedback | |
hr | |
- if (item.TextArea1) | |
h5 TextArea1: | |
p | |
!= item.TextArea1 | |
hr | |
- if (item.TextArea2) | |
h5 TextField2: | |
p | |
!= item.TextArea2 | |
hr | |
Now that the templates are done, we are ready to rock. Start it up
$ coffee app.coffee
Print to PDF. Look at that! A nice report generated with page breaks on each main topic (item) based on SharePoint 2010 data in a simple yet expressive way.