4

I've been searching everywhere trying to figure this one out. I'm trying to generate html pages from couchdb show and list functions. I'd like to leverage underscore.js's template solution. The part I'm getting stuck on is how to include html templates in my show and list functions.

Where do I store them? As attachments? And then how do I reference them in my show and list functions. I assume !json and !code macros are not being used, and I can't figure out how to use require() from common js to do it.

Any help would rock!

Thanks!

Extra Info: I'm using Kanso to push my apps, not CouchApp.

Adrian Heine
  • 4,051
  • 2
  • 30
  • 43
Costa Michailidis
  • 7,691
  • 15
  • 72
  • 124

2 Answers2

5

CouchDB attachments are, by definition, not accessible in show and list functions.

Show and list functions support CommonJS. So you simply need to include any libraries in the design doc.

{ "_id": "_design/example"
, "say_hi": "module.exports = function(person) { return 'Hello, ' + person }"
, "shows":
  { "hello": "function(doc, req) { var hi = require('say_hi'); return hi(req.query.me) }"
  }
}

This view would look like this

GET /my_db/_design/example/_show/hello?me=Jason

HTTP/1.1 200 OK
Server: CouchDB/1.2.0 (Erlang OTP/R15B)
Date: Fri, 06 Apr 2012 11:02:33 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 12


Hello, Jason
Community
  • 1
  • 1
JasonSmith
  • 72,674
  • 22
  • 123
  • 149
  • Thanks for the quick reply! That's great, I've got it up to that point, but is there a way to include html templates (or css for that matter)? Creating my templates as javascript strings is really difficult to maintain in the long run. – Costa Michailidis Apr 06 '12 at 15:22
  • Yes, in the map function, `this` is a reference to the design document. If you have `"hello":"Hello, {{user}}"` in the design document, then inside the map function, you can reference `this.hello` and get the string `"Hello, {{user}}"`. – JasonSmith Apr 07 '12 at 05:15
  • Thanks so much Jason! This is great! Hey, I've been learning quite a bit on how to use CouchDB, is there any way to help out? Teaching others? Adding a couchapp to the community? etc... – Costa Michailidis Apr 07 '12 at 07:07
  • You're welcome. I actually like @Slartibartfast's answer better now that it has the history of how things work :) – JasonSmith Apr 07 '12 at 07:49
  • 1
    @Costa I *highly* recommend that you email the CouchDB users list with questions about that. If you want to build experience with couch apps, I have a *million* apps I wish the community had, and everybody else has ideas too! – JasonSmith Apr 07 '12 at 07:50
  • Perfect, I'll do that...oh wow, new couchdb.org site. Thanks for all the help Jason! Is there a new york based user's group or any events around couchdb? – Costa Michailidis Apr 07 '12 at 17:16
  • Awesome! Unfortunately I am unsure about New York (I live 14,000 km away), but the mailing list is a great place to find local communities too. People do those sorts of events in California all the time. – JasonSmith Apr 08 '12 at 00:14
  • Haha, gotcha. Maybe I can organize something for CouchDB user's in New York someday. – Costa Michailidis Apr 08 '12 at 23:02
  • Tools like couchapp or Kanso will let you write your templates as simple, unencoded files (that you can edit with your favorite editor, keep under version control, etc.) and do the work of encoding them and sticking them into your design document when you do a push. – ebohlman May 04 '12 at 20:43
4

I'm unfamiliar with Kanso, but before CouchDB 1.1, view/show etc. functions in CouchDB could not include anything. (The CouchApp tool had its own !include workarounds to solve this.) These are not necessary anymore. CouchDB 1.1 added CommonJS support.

Tll the templates and libraries must be part of the design document. You can access the raw values (as a string) by referencing this.some_key; or load them via CommonJS by executing require("some_key").

For example:

exports.example_view = {
    map: function (doc) {
        // this must be placed *inside* the map function
        var example = require('views/lib/example');
        if (doc.num) {
            emit(doc._id, example.fn());
        }
    }
};

(Sharing code between views)

To render templates server-side, you'll need to encode them as string and require them like you require other JavaScript libraries. (For browser-side rendering, fetching attachments via AJAX works.)

JasonSmith
  • 72,674
  • 22
  • 123
  • 149
Slartibartfast
  • 8,735
  • 6
  • 41
  • 45
  • Thanks! Encoding my templates as strings is exactly what I'm trying to avoid. I'm going to look for some kind of pre-processor next. – Costa Michailidis Apr 06 '12 at 15:23
  • View/show **can** include anything, using CommonJS. In your example, Kanso (while excellent) is irrelevant. The `require()` in the map function occurs within CouchDB. – JasonSmith Apr 07 '12 at 05:04
  • @JasonSmith That's interesting. Is that a recent change? Why CoichApp had macros for including? – Slartibartfast Apr 07 '12 at 06:15
  • @Slartibartfast It arrived in CouchDB 1.1. The old CouchApp functionality was a workaround. I took the liberty of updating your answer to tell the long sordid saga :) – JasonSmith Apr 07 '12 at 06:43
  • Thanks, guys, this clears up quite a bit! So far I'm able to include underscore using require, include html templates with this.templates or require, and compile templates with _.template to display my content with list functions. My next goal is to see if I can create a whole dynamic html page (css, js, imgs, fonts and all) and make it available with one GET request through a couchdb list function. I'd be totally fine with 3 or 4 requests, but it'll be a fun challenge. – Costa Michailidis Apr 07 '12 at 07:05
  • Just to clarify, CommonJS support for views/shows/updates/validations was added in 0.11. 1.1 added support for it in map functions (it's still not available for reduce functions). – ebohlman May 04 '12 at 20:32