Skip to content

Commit

Permalink
Generate static HTML blog content out of markdown
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Jun 21, 2012
1 parent ebdc029 commit bbd58f3
Show file tree
Hide file tree
Showing 166 changed files with 11,944 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -18,6 +18,7 @@ node_g
# various stuff that VC++ produces/uses
Debug/
Release/
!doc/blog/**
*.sln
!nodemsi.sln
*.suo
Expand All @@ -39,6 +40,5 @@ ipch/
/npm.wxs
/tools/msvs/npm.wixobj
email.md
blog.html
deps/v8-*
./node_modules
13 changes: 11 additions & 2 deletions Makefile
Expand Up @@ -130,7 +130,13 @@ website_files = \
out/doc/changelog.html \
$(doc_images)

doc: program $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs) tools/doc/
doc: program $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs) tools/doc/ blog

blogclean:
rm -rf out/blog

blog: doc/blog out/Release/node tools/blog
out/Release/node tools/blog/generate.js doc/blog/ out/blog/ doc/blog.html

$(apidoc_dirs):
mkdir -p $@
Expand Down Expand Up @@ -160,6 +166,9 @@ email.md: ChangeLog tools/email-footer.md
blog.html: email.md
cat $< | ./node tools/doc/node_modules/.bin/marked > $@

blog-upload: blog
rsync -r out/blog/ node@nodejs.org:~/web/nodejs.org/blog/

website-upload: doc
rsync -r out/doc/ node@nodejs.org:~/web/nodejs.org/
ssh node@nodejs.org '\
Expand Down Expand Up @@ -260,4 +269,4 @@ cpplint:

lint: jslint cpplint

.PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean check uninstall install install-includes install-bin all program staticlib dynamiclib test test-all website-upload pkg
.PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean check uninstall install install-includes install-bin all program staticlib dynamiclib test test-all website-upload pkg blog blogclean
209 changes: 209 additions & 0 deletions doc/blog.html
@@ -0,0 +1,209 @@
<!DOCTYPE html>

<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://nodejs.org/pipe.css">
<link rel="stylesheet" href="http://nodejs.org/sh_vim-dark.css">
<style>
#column1 h1 {
clear:both;
}
#column1 li, #content h1 + p {
color:inherit;
font-family: inherit;
font-size: 14px;
line-height:24px;
}
#content #column1 p.meta, #content #column1 p.respond {
font-size: 14px;
line-height: 24px;
color:#690;
font-family: inherit;
}
#content #column1 p.respond {
font-style:italic;
padding:2em 0;
}
#column1 a {
color: #8c0;
}
#column2 ul {
padding:0;
}
#column2 {
margin-top:-66px!important;
}
div.post-in-feed {
padding-bottom:1em;
}

p.next { float:right; width: 40%; text-align:right; }
p.prev { float:left; width:40%; text-align:left; }

pre { overflow: auto; }
</style>

<title><%= title %></title>
</head>

<body class="int blog" id="<%= pageid %>">
<div id="intro" class="interior">
<a href="/" title="Go back to the home page"><img id="logo" src=
"http://nodejs.org/logo.png" alt="node.js"></a>
</div>

<div id="content" class="clearfix">
<div id="column2" class="interior">
<ul>
<li><a href="http://nodejs.org/" class="home">Home</a></li>

<li><a href="http://nodejs.org/#download" class=
"download">Download</a></li>

<li><a href="http://nodejs.org/about/" class="about">About</a></li>

<li><a href="http://search.npmjs.org/" class="npm">npm
Registry</a></li>

<li><a href="http://nodejs.org/api/" class="docs">Docs</a></li>

<li><a href="http://blog.nodejs.org/" class="blog current">Blog</a></li>

<li><a href="http://nodejs.org/community/" class=
"community">Community</a></li>

<li><a href="http://nodejs.org/logos/" class=
"logos">Logos</a></li>

<li><a href="http://jobs.nodejs.org/" class="jobs">Jobs</a></li>
</ul>

<p class="twitter"><a href="http://twitter.com/nodejs">@nodejs</a></p>
</div>

<div id="column1" class="interior">
<h1><%- title %></h1>
<% if (typeof post !== 'undefined') {
// just one post on this page
%>
<p class="meta"><%=
post.author + ' - ' +
post.date.toUTCString().replace(/ GMT$/, '')
%></p>

<%- post.content %>

<p class="respond">Please post feedback and comments on
<a href="https://groups.google.com/group/nodejs">the Node.JS
user mailing list</a>.</p>

<%
if (post.next || post.prev) {
if (post.prev) {
%><p class="prev"><a href="<%=
post.prev.permalink
%>">&larr; <%=
post.prev.title
%></a></p>
<%
}
if (post.next) {
%><p class="next"><a href="<%=
post.next.permalink
%>"><%=
post.next.title
%> &rarr;</a></p>
<%
}
}
} else { // not single post page
if (paginated && total > 1 ) {
if (page > 0) {
// add 1 to all of the displayed numbers, because
// humans are not zero-indexed like they ought to be.
%>
<p class="prev"><a href="<%= uri + (page - 1) %>">
&larr; Page <%- page %>
</a></p>
<%
}
if (page < total - 1) { %>
<p class="next"><a href="<%= uri + (page + 1) %>">
Page <%- page + 2 %> &rarr;
</a></p>
<%
}
}

posts.forEach(function(post) {
%>
<div class="post-in-feed">
<h1><a href="<%=
post.permalink
%>" class="permalink"><%-
post.title
%></a></h1>
<p class="meta"><%=
post.author + ' - ' +
post.date.toUTCString().replace(/ GMT$/, '')
%></p>
<%- post.content %>
</div>
<%
});

if (paginated && total > 1 ) {
if (page > 0) {
// add 1 to all of the displayed numbers, because
// humans are not zero-indexed like they ought to be.
%>
<p class="prev"><a href="<%= uri + (page - 1) %>">
&larr; Page <%- page %>
</a></p>
<%
}
if (page < total - 1) { %>
<p class="next"><a href="<%= uri + (page + 1) %>">
Page <%- page + 2 %> &rarr;
</a></p>
<%
}
} // pagination
} // not a single post
%>
</div>
</div>

<div id="footer">
<ul class="clearfix">
<li><a href="/">Node.js</a></li>
<li><a href="/#download">Download</a></li>
<li><a href="/about/">About</a></li>
<li><a href="http://search.npmjs.org/">npm Registry</a></li>
<li><a href="http://nodejs.org/api/">Docs</a></li>
<li><a href="http://blog.nodejs.org">Blog</a></li>
<li><a href="/community/">Community</a></li>
<li><a href="/logos/">Logos</a></li>
<li><a href="http://jobs.nodejs.org/">Jobs</a></li>
<li><a href="http://twitter.com/nodejs" class="twitter">@nodejs</a></li>
</ul>

<p>Copyright <a href="http://joyent.com">Joyent, Inc</a>, Node.js is a <a href="/trademark-policy.pdf">trademark</a> of Joyent, Inc. View <a href="https://raw.github.com/joyent/node/master/LICENSE">license</a>.</p>
</div>

<script src="../sh_main.js"></script>
<script src="../sh_javascript.min.js"></script>
<script>highlight(undefined, undefined, 'pre');</script>
<script>
var gaJsHost = (("https:" == document.location.protocol) ?
"https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script>
try {
var pageTracker = _gat._getTracker("UA-10874194-2");
pageTracker._trackPageview();
} catch(err) {}</script>
</body>
</html>
12 changes: 4 additions & 8 deletions doc/blog/Uncategorized/ldapjs-a-reprise-of-ldap.md
Expand Up @@ -7,6 +7,7 @@ slug: ldapjs-a-reprise-of-ldap

This post has been about 10 years in the making. My first job out of college was at IBM working on the <a title="Tivoli Directory Server" href="http://www-01.ibm.com/software/tivoli/products/directory-server/">Tivoli Directory Server</a>, and at the time I had a preconceived notion that working on anything related to Internet RFCs was about as hot as you could get. I spent a lot of time back then getting "down and dirty" with everything about LDAP: the protocol, performance, storage engines, indexing and querying, caching, customer use cases and patterns, general network server patterns, etc. Basically, I soaked up as much as I possibly could while I was there. On top of that, I listened to all the "gray beards" tell me about the history of LDAP, which was a bizarre marriage of telecommunications conglomerates and graduate students. The point of this blog post is to give you a crash course in LDAP, and explain what makes <a title="ldapjs" href="http://ldapjs.org">ldapjs</a> different. Allow me to be the gray beard for a bit...
<h2>What is LDAP and where did it come from?</h2>

Directory services were largely pioneered by the telecommunications companies (e.g., AT&amp;T) to allow fast information retrieval of all the crap you'd expect would be in a telephone book and directory. That is, given a name, or an address, or an area code, or a number, or a foo support looking up customer records, billing information, routing information, etc. The efforts of several telcos came to exist in the <a title="X.500" href="http://en.wikipedia.org/wiki/X.500">X.500</a> standard(s). An X.500 directory is one of the most complicated beasts you can possibly imagine, but on a high note, there's
probably not a thing you can imagine in a directory service that wasn't thought of in there. It is literally the kitchen sink. Oh, and it doesn't run over IP (it's <em>actually</em> on the <a title="OSI Model" href="http://en.wikipedia.org/wiki/OSI_model">OSI</a> model).

Expand All @@ -22,6 +23,7 @@ Macro point is that there have actually been very few "fresh" implementations o

That said, while there certainly is some wacky stuff in the LDAP protocol itself, it really suffered from poor and buggy implementations more than the fact that LDAP itself was fundamentally flawed. As <a title="Engine Yard LDAP" href="http://www.engineyard.com/blog/2009/ldap-directories-the-forgotten-nosql/">engine yard pointed out a few years back</a>, you can think of LDAP as the original NoSQL store.
<h2>LDAP: The Good Parts</h2>

So what's awesome about LDAP? Since it's a directory system it maintains a hierarchy of your data, which as an information management pattern aligns
with _a lot_ of use case (the quintessential example is white pages for people in your company, but subscriptions to SaaS applications, "host groups"
for tracking machines/instances, physical goods tracking, etc., all have use cases that fit that organization scheme). For example, presumably at your job
Expand Down Expand Up @@ -50,14 +52,14 @@ I could keep going, but the gist is that LDAP has "full" boolean predicate logi

Oh, and on top of the technical merits, better or worse, it's an established standard for both administrators and applications (i.e., most "shipped" intranet software has either a local user repository or the ability to leverage an LDAP server somewhere). So there's a lot of compelling reasons to look at leveraging LDAP.
<h2>ldapjs: Why do I care?</h2>

As I said earlier, I spent a lot of time at IBM observing how customers used LDAP, and the real items I took away from that experience were:
<ul>
<li>LDAP implementations have suffered a lot from never having been designed from the ground up for a large number of concurrent connections with asynchronous operations.</li>
<li>There are use cases for LDAP that just don't always fit the traditional "here's my server and storage engine" model. A lot of simple customer use cases wanted an LDAP access point, but not be forced into taking the heavy backends that came with it (they wanted the original gateway model!). There was an entire "sub" industry for this known as "<a title="Metadirectory" href="http://en.wikipedia.org/wiki/Metadirectory">meta directories</a>" back in the late 90's and early 2000's.</li>
<li>Replication was always a sticking point. LDAP vendors all tried to offer a big multi-master, multi-site replication model. It was a lot of "bolt-on" complexity, done before the <a title="CAP Theorem" href="http://en.wikipedia.org/wiki/CAP_theorem">CAP theorem</a> was written, and certainly before it was accepted as "truth."</li>
<li>Nobody uses all of the protocol. In fact, 20% of the features solve 80% of the use cases (I'm making that number up, but you get the idea).</li>
</ul>
<div>

For all the good parts of LDAP, those are really damned big failing points, and even I eventually abandoned LDAP for the greener pastures of NoSQL somewhere
along the way. But it always nagged at me that LDAP didn't get it's due because of a lot of implementation problems (to be clear, if I could, I'd change some
Expand All @@ -70,19 +72,13 @@ Well, in the last year, I went to work for <a title="Joyent" href="http://www.jo
<li><strong>Replication is hard. CAP is right:</strong> There are a lot of distributed databases out vying to solve exactly this problem. At Joyent we went with <a title="Riak" href="http://www.basho.com/">Riak</a>. Check!</li>
<li><strong>Don't need all of the protocol:</strong> I'm lazy. Let's just skip the stupid things most people don't need. Check!</li>
</ul>
<div>

So that's the crux of ldapjs right there. Giving you the ability to put LDAP back into your application while nailing those 4 fundamental problems that plague most existing LDAP deployments.

The obvious question is how it turned out, and the answer is, honestly, better than I thought it would. When I set out to do this, I actually assumed I'd be shipping a much smaller percentage of the RFC than is there. There's actually about 95% of the core RFC implemented. I wasn't sure if the marriage of this protocol to node/JavaScript would work out, but if you've used express ever, this should be _really_ familiar. And I tried to make it as natural as possible to use "pure" JavaScript objects, rather than requiring the developer to understand <a title="ASN.1" href="http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One">ASN.1</a> (the binary wire protocol) or the<a title="RFC 4510" href="http://tools.ietf.org/html/rfc4510"> LDAP RFC</a> in detail (this one mostly worked out; ldap_modify is still kind of a PITA).

Within 24 hours of releasing ldapjs on <a title="twitter" href="http://twitter.com/#!/mcavage/status/106767571012952064">Twitter</a>, there was an <a title="github ldapjs address book" href="https://gist.github.com/1173999">implementation of an address book</a> that works with Thunderbird/Evolution, by the end of that weekend there was some <a href="http://i.imgur.com/uR16U.png">slick integration with CouchDB</a>, and ldapjs even got used in one of the <a href="http://twitter.com/#!/jheusala/status/108977708649811970">node knockout apps</a>. Off to a pretty good start!

</div>
</div>
<h2>The Road Ahead</h2>
<div>


Hopefully you've been motivated to learn a little bit more about LDAP and try out <a href="http://ldapjs.org">ldapjs</a>. The best place to start is probably the <a title="ldapjs guide" href="http://ldapjs.org/guide.html">guide</a>. After that you'll probably need to pick up a book from <a href="http://www.amazon.com/Understanding-Deploying-LDAP-Directory-Services/dp/0672323168">back in the day</a>. ldapjs itself is still in its infancy; there's quite a bit of room to add some slick client-side logic (e.g., connection pools, automatic reconnects), easy to use schema validation, backends, etc. By the time this post is live, there will be experimental <a href="http://en.wikipedia.org/wiki/DTrace">dtrace</a> support if you're running on Mac OS X or preferably Joyent's <a href="http://smartos.org/">SmartOS</a> (shameless plug). And that nagging percentage of the protocol I didn't do will get filled in over time I suspect. If you've got an interest in any of this, send me some pull requests, but most importantly, I just want to see LDAP not just be a skeleton in the closet and get used in places where you should be using it. So get out there and write you some LDAP.

</div>
13 changes: 0 additions & 13 deletions doc/blog/Uncategorized/welcome-to-the-node-blog.md

This file was deleted.

0 comments on commit bbd58f3

Please sign in to comment.