Permalink
Browse files

Generate static HTML blog content out of markdown

  • Loading branch information...
1 parent ddf52bd commit 8f1a38d916326e37bc830a5c56c5d42866c8c423 @isaacs isaacs committed Jun 20, 2012
Showing with 11,944 additions and 41 deletions.
  1. +1 −1 .gitignore
  2. +11 −2 Makefile
  3. +209 −0 doc/blog.html
  4. +4 −8 doc/blog/Uncategorized/ldapjs-a-reprise-of-ldap.md
  5. +0 −13 doc/blog/Uncategorized/welcome-to-the-node-blog.md
  6. +8 −8 doc/blog/module/multi-server-continuous-deployment-with-fleet.md
  7. +1 −1 doc/blog/npm/managing-node-js-dependencies-with-shrinkwrap.md
  8. +25 −0 doc/blog/release/node-v0-4-10.md
  9. +39 −0 doc/blog/release/node-v0-4-11.md
  10. +29 −0 doc/blog/release/node-v0-4-12.md
  11. +33 −0 doc/blog/release/node-v0-4-3.md
  12. +27 −0 doc/blog/release/node-v0-4-4.md
  13. +29 −0 doc/blog/release/node-v0-4-5.md
  14. +27 −0 doc/blog/release/node-v0-4-6.md
  15. +23 −0 doc/blog/release/node-v0-4-7.md
  16. +55 −0 doc/blog/release/node-v0-4-8.md
  17. +30 −0 doc/blog/release/node-v0-4-9.md
  18. +39 −0 doc/blog/release/node-v0-5-0-unstable.md
  19. +30 −0 doc/blog/release/node-v0-5-1.md
  20. +41 −0 doc/blog/release/node-v0-5-10.md
  21. +27 −0 doc/blog/release/node-v0-5-2.md
  22. +53 −0 doc/blog/release/node-v0-5-3.md
  23. +36 −0 doc/blog/release/node-v0-5-4.md
  24. +40 −0 doc/blog/release/node-v0-5-5.md
  25. +49 −0 doc/blog/release/node-v0-5-6.md
  26. +35 −0 doc/blog/release/node-v0-5-7-unstable.md
  27. +26 −0 doc/blog/release/node-v0-5-8.md
  28. +27 −0 doc/blog/release/node-v0-5-9.md
  29. +80 −0 doc/blog/release/node-v0-6-0.md
  30. +33 −0 doc/blog/release/node-v0-6-1.md
  31. +30 −0 doc/blog/release/node-v0-6-10.md
  32. +27 −0 doc/blog/release/node-v0-6-2.md
  33. +30 −0 doc/blog/release/node-v0-6-3.md
  34. +31 −0 doc/blog/release/node-v0-6-4.md
  35. +21 −0 doc/blog/release/node-v0-6-5.md
  36. +32 −0 doc/blog/release/node-v0-6-6.md
  37. +41 −0 doc/blog/release/node-v0-6-7.md
  38. +31 −0 doc/blog/release/node-v0-6-8.md
  39. +30 −0 doc/blog/release/node-v0-6-9.md
  40. +29 −0 doc/blog/release/node-v0-7-0-unstable.md
  41. +30 −0 doc/blog/release/node-v0-7-1.md
  42. +32 −0 doc/blog/release/node-v0-7-2-unstable.md
  43. +39 −0 doc/blog/release/node-v0-7-3.md
  44. +61 −0 doc/blog/release/node-version-0-6-19-stable.md
  45. +73 −0 doc/blog/release/node-version-0-7-9-unstable.md
  46. +64 −0 doc/blog/release/version-0-6-11-stable.md
  47. +66 −0 doc/blog/release/version-0-6-12-stable.md
  48. +50 −0 doc/blog/release/version-0-6-13-stable.md
  49. +55 −0 doc/blog/release/version-0-6-14-stable.md
  50. +53 −0 doc/blog/release/version-0-6-15-stable.md
  51. +59 −0 doc/blog/release/version-0-6-16-stable.md
  52. +47 −0 doc/blog/release/version-0-6-17-stable.md
  53. +59 −0 doc/blog/release/version-0-6-18-stable.md
  54. +86 −0 doc/blog/release/version-0-7-10-unstable.md
  55. +80 −0 doc/blog/release/version-0-7-11-unstable.md
  56. +56 −0 doc/blog/release/version-0-7-12.md
  57. +50 −0 doc/blog/release/version-0-7-4-unstable.md
  58. +62 −0 doc/blog/release/version-0-7-5-unstable.md
  59. +72 −0 doc/blog/release/version-0-7-6-unstable.md
  60. +71 −0 doc/blog/release/version-0-7-7-unstable.md
  61. +71 −0 doc/blog/release/version-0-7-8-unstable.md
  62. +25 −2 doc/blog/video/bryan-cantrill-instrumenting-the-real-time-web.md
  63. +3 −3 doc/blog/video/welcome-to-the-node-blog.md
  64. +3 −3 doc/blog/vulnerability/http-server-security-vulnerability-please-upgrade-to-0-6-17.md
  65. +5 −0 tools/blog/README.md
  66. +261 −0 tools/blog/generate.js
  67. +1 −0 tools/blog/node_modules/.bin/marked
  68. 0 tools/blog/node_modules/ejs/.gitmodules
  69. +4 −0 tools/blog/node_modules/ejs/.npmignore
  70. +98 −0 tools/blog/node_modules/ejs/History.md
  71. +23 −0 tools/blog/node_modules/ejs/Makefile
  72. +151 −0 tools/blog/node_modules/ejs/Readme.md
  73. +14 −0 tools/blog/node_modules/ejs/benchmark.js
  74. +567 −0 tools/blog/node_modules/ejs/ejs.js
  75. +2 −0 tools/blog/node_modules/ejs/ejs.min.js
  76. +24 −0 tools/blog/node_modules/ejs/examples/client.html
  77. +7 −0 tools/blog/node_modules/ejs/examples/list.ejs
  78. +14 −0 tools/blog/node_modules/ejs/examples/list.js
  79. +2 −0 tools/blog/node_modules/ejs/index.js
  80. +298 −0 tools/blog/node_modules/ejs/lib/ejs.js
  81. +198 −0 tools/blog/node_modules/ejs/lib/filters.js
  82. +23 −0 tools/blog/node_modules/ejs/lib/utils.js
  83. +23 −0 tools/blog/node_modules/ejs/package.json
  84. +174 −0 tools/blog/node_modules/ejs/support/compile.js
  85. +329 −0 tools/blog/node_modules/ejs/test/ejs.test.js
  86. +1 −0 tools/blog/node_modules/ejs/test/fixtures/user.ejs
  87. +2 −0 tools/blog/node_modules/glob/.npmignore
  88. +4 −0 tools/blog/node_modules/glob/.travis.yml
  89. +25 −0 tools/blog/node_modules/glob/LICENCE
  90. +233 −0 tools/blog/node_modules/glob/README.md
  91. +9 −0 tools/blog/node_modules/glob/examples/g.js
  92. +9 −0 tools/blog/node_modules/glob/examples/usr-local.js
  93. +601 −0 tools/blog/node_modules/glob/glob.js
  94. +1 −0 tools/blog/node_modules/glob/node_modules/graceful-fs/.npmignore
  95. +23 −0 tools/blog/node_modules/glob/node_modules/graceful-fs/LICENSE
  96. +5 −0 tools/blog/node_modules/glob/node_modules/graceful-fs/README.md
  97. +275 −0 tools/blog/node_modules/glob/node_modules/graceful-fs/graceful-fs.js
  98. +22 −0 tools/blog/node_modules/glob/node_modules/graceful-fs/package.json
  99. +51 −0 tools/blog/node_modules/glob/node_modules/inherits/README.md
  100. +29 −0 tools/blog/node_modules/glob/node_modules/inherits/inherits.js
  101. +25 −0 tools/blog/node_modules/glob/node_modules/inherits/package.json
  102. +4 −0 tools/blog/node_modules/glob/node_modules/minimatch/.travis.yml
  103. +23 −0 tools/blog/node_modules/glob/node_modules/minimatch/LICENSE
  104. +218 −0 tools/blog/node_modules/glob/node_modules/minimatch/README.md
  105. +1,052 −0 tools/blog/node_modules/glob/node_modules/minimatch/minimatch.js
  106. +1 −0 tools/blog/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
  107. +5 −0 tools/blog/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/AUTHORS
  108. +23 −0 tools/blog/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
  109. +26 −0 tools/blog/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
  110. +156 −0 tools/blog/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
  111. +45 −0 tools/blog/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
  112. +171 −0 tools/blog/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
  113. +36 −0 tools/blog/node_modules/glob/node_modules/minimatch/package.json
  114. +273 −0 tools/blog/node_modules/glob/node_modules/minimatch/test/basic.js
  115. +33 −0 tools/blog/node_modules/glob/node_modules/minimatch/test/brace-expand.js
  116. +14 −0 tools/blog/node_modules/glob/node_modules/minimatch/test/caching.js
  117. +274 −0 tools/blog/node_modules/glob/node_modules/minimatch/test/defaults.js
  118. +35 −0 tools/blog/node_modules/glob/package.json
  119. +61 −0 tools/blog/node_modules/glob/test/00-setup.js
  120. +119 −0 tools/blog/node_modules/glob/test/bash-comparison.js
  121. +55 −0 tools/blog/node_modules/glob/test/cwd-test.js
  122. +98 −0 tools/blog/node_modules/glob/test/pause-resume.js
  123. +39 −0 tools/blog/node_modules/glob/test/root-nomount.js
  124. +43 −0 tools/blog/node_modules/glob/test/root.js
  125. +11 −0 tools/blog/node_modules/glob/test/zz-cleanup.js
  126. +2 −0 tools/blog/node_modules/marked/.npmignore
  127. +19 −0 tools/blog/node_modules/marked/LICENSE
  128. +9 −0 tools/blog/node_modules/marked/Makefile
  129. +125 −0 tools/blog/node_modules/marked/README.md
  130. +127 −0 tools/blog/node_modules/marked/bin/marked
  131. +1 −0 tools/blog/node_modules/marked/index.js
  132. +791 −0 tools/blog/node_modules/marked/lib/marked.js
  133. +49 −0 tools/blog/node_modules/marked/man/marked.1
  134. +40 −0 tools/blog/node_modules/marked/package.json
  135. +2 −0 tools/blog/node_modules/mkdirp/.gitignore.orig
  136. +5 −0 tools/blog/node_modules/mkdirp/.gitignore.rej
  137. +2 −0 tools/blog/node_modules/mkdirp/.npmignore
  138. +4 −0 tools/blog/node_modules/mkdirp/.travis.yml
  139. +21 −0 tools/blog/node_modules/mkdirp/LICENSE
  140. +61 −0 tools/blog/node_modules/mkdirp/README.markdown
  141. +6 −0 tools/blog/node_modules/mkdirp/examples/pow.js
  142. +6 −0 tools/blog/node_modules/mkdirp/examples/pow.js.orig
  143. +19 −0 tools/blog/node_modules/mkdirp/examples/pow.js.rej
  144. +94 −0 tools/blog/node_modules/mkdirp/index.js
  145. +32 −0 tools/blog/node_modules/mkdirp/package.json
  146. +38 −0 tools/blog/node_modules/mkdirp/test/chmod.js
  147. +37 −0 tools/blog/node_modules/mkdirp/test/clobber.js
  148. +28 −0 tools/blog/node_modules/mkdirp/test/mkdirp.js
  149. +32 −0 tools/blog/node_modules/mkdirp/test/perm.js
  150. +39 −0 tools/blog/node_modules/mkdirp/test/perm_sync.js
  151. +41 −0 tools/blog/node_modules/mkdirp/test/race.js
  152. +32 −0 tools/blog/node_modules/mkdirp/test/rel.js
  153. +25 −0 tools/blog/node_modules/mkdirp/test/return.js
  154. +24 −0 tools/blog/node_modules/mkdirp/test/return_sync.js
  155. +18 −0 tools/blog/node_modules/mkdirp/test/root.js
  156. +32 −0 tools/blog/node_modules/mkdirp/test/sync.js
  157. +28 −0 tools/blog/node_modules/mkdirp/test/umask.js
  158. +32 −0 tools/blog/node_modules/mkdirp/test/umask_sync.js
  159. +23 −0 tools/blog/node_modules/semver/LICENSE
  160. +119 −0 tools/blog/node_modules/semver/README.md
  161. +71 −0 tools/blog/node_modules/semver/bin/semver
  162. +26 −0 tools/blog/node_modules/semver/package.json
  163. +305 −0 tools/blog/node_modules/semver/semver.js
  164. +405 −0 tools/blog/node_modules/semver/test.js
  165. +1 −0 tools/blog/templates/index.ejs
  166. +189 −0 tools/blog/wp-to-markdown.js
View
@@ -18,6 +18,7 @@ node_g
# various stuff that VC++ produces/uses
Debug/
Release/
+!doc/blog/**
*.sln
!nodemsi.sln
*.suo
@@ -39,6 +40,5 @@ ipch/
/npm.wxs
/tools/msvs/npm.wixobj
email.md
-blog.html
deps/v8-*
./node_modules
View
@@ -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 $@
@@ -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 '\
@@ -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
View
@@ -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>
@mathiasbynens

mathiasbynens Jun 22, 2012

Nit: the next few lines are the old Google Analytics script that relies on document.write(). Why not use the optimized version of the updated, asynchronous snippet?

Relevant pull request: #3298.

+ 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>
@@ -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).
@@ -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
@@ -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
@@ -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>
@@ -1,13 +0,0 @@
-title: Welcome to the Node blog
-author: ryandahl
-date: Thu Mar 17 2011 20:17:12 GMT-0700 (PDT)
-status: publish
-category: Uncategorized
-slug: welcome-to-the-node-blog
-
-Since Livejournal is disintegrating into Russian spam, I'm moving my technical blog to http://blog.nodejs.org/. I hope to do frequent small posts about what's going on in Node development and include posts from other core Node developers. Please subscribe to the RSS feed.
-
-To avoid making this post completely devoid of content, here is a new video from a talk I gave at the SF PHP group tastefully produced by <A href="http://marakana.com/forums/java/general/278.html">Marakana</a>:
-<iframe width="640" height="360"
-src="http://www.youtube.com/embed/jo_B4LTHi3I" frameborder="0"
-allowfullscreen></iframe>
Oops, something went wrong.

0 comments on commit 8f1a38d

Please sign in to comment.