Dear wiki user, You have subscribed to a wiki page "Couchdb Wiki" for change notification.
The page "Advanced_Shows_and_Lists_Throwing_Redirects" has been deleted by JoanTouzet: https://wiki.apache.org/couchdb/Advanced_Shows_and_Lists_Throwing_Redirects?action=diff&rev1=5&rev2=6 Comment: Migrated to https://docs.couchdb.org/en/latest/ddocs/ddocs.html - <<Include(EditTheWiki)>> - ## page was renamed from Advanced Shows and Lists: Throwing Redirects - ## page was renamed from Throw a 404 or a redirect - = Advanced Shows and Lists: Throwing Redirects = - - == Throw a 404 error == - - To throw a 404 from inside a _show or _list func .. the easiest way is: - - {{{ - throw (['error', 'not_found', 'Some message like Page not found']) - }}} - - That will be caught by the top level loop thing and turned into a nice response. - - == Return a redirect == - - There's no top level catcher thing for redirects, so you can't *throw a redirect*, you have to 'return' it. - - To do a redirect, there's a library function that will do it for you: - - {{{ - var redirect = require("vendor/couchapp/lib/redirect"); - return redirect.permanent('http://some.new/place'); - }}} - - You can use the path lib to help get some neat urls, have a look at vendor/couchapp/lib/path.js source .. - - What this actually does is the equivalent of: - - {{{ - return { code : 301, headers : { "Location" : 'http://some.new/place' } }; - }}} - - The 'code' is the http response code, the http response would be something like: - - {{{ - HTTP/1.1 301 Moved Permanently - Vary: Accept - Server: CouchDB/1.0.1 (Erlang OTP/R13B) - Location: http://foot:5984/products/dvrs/standalone-h.264-16-channel-dvr - Etag: "CYFPH3WEUO9R5B8S26QWV3NK4" - Date: Sat, 11 Sep 2010 04:51:37 GMT - Content-Type: application/json - Content-Length: 0 - }}} - - = Case study, Making a Redirect Throwable = - - If you're deep in a lib/mystuff.js func, I use this sort of style for a certain checker function. - - In this example I have different product lines in my rewrites, of the form: - - {{{ - [ - { - "from": "/products/dvrs", - "to": "_list/dvrs", - "method": "GET" - }, - { - "from": "/products/dvrs/new", - "to": "_show/dvr-new", - "method": "GET" - }, - { - "from": "/products/dvrs/new", - "to": "_show/dvr-save", - "method": "POST" - }, - { - "from": "/products/dvrs/*", - "to": "_show/dvr/*", - "method": "GET" - }, - // Then a bunch of similar things for other product lines (like /products/cameras/ etc ..) - ] - }}} - - The trouble is if someone uses the wrong url for the type of product, I want to put them right, this will help keep the - search engine optimization good too. So if someone goes: - - {{{ - http://mysite.kom/products/cameras/id_of_a_dvr - }}} - - It will call the _show/camera method with the id of a document that has {type: 'dvr'}. Which is bad because I use a - different template but also bad because SEO will freak out if it ends up in google. - - To fix it I did the following: - - In my _show or _list func I put: - - {{{ - var rewrite = require("lib/rewritehelper").init(req); - // If we're trying to use this view to see something other than a dvr, make sure we're looking at the right type - try {rewrite.checkType(doc, 'camera');} catch (e) {return e;} - }}} - - I know people will yell at me for puting too much on one line. But I'm using this in all my _show and _list funcs, I - want it to be nice and short. - - In my *lib/rewritehelper.js* file I check the type and all that and if it's wrong I throw an exception, which the _show - func catches and returns as is. Here's the full code for my lib function so far: - - {{{ - /* Helps you get the rewrites right. - - Complements the rewrites.json .. really both should be updated at the same time. Saves having to update every place you - put a path to something. - - */ - - exports.init = function(req) { - - rewrite = {}; - - rewrite.url4doc = function (_id, prodType) { - /* Returns a url to a product, takes doc._id and doc._type */ - // See if it's a product - switch (prodType) { - case "forum-topic": - case "forum-post": - return "http://" + req.headers.Host + "/forums/" + prodType + "s/" + _id; - case "support": - return "http://" + req.headers.Host + "/support/" + prodType + "s/" + _id; - case "dvr": - case "camera": - return "http://" + req.headers.Host + "/products/" + prodType + "s/" + _id; - default: - return {code: 404, body: 'Page not found!'} - }; - }; - rewrite.checkType = function (doc, desiredType) { - /* Checks a document type and throws an exception that should be returned straight to the client if caught. - If no exception is raised, the check has passed */ - if ((doc) && (doc.type != desiredType)) { - var newURL = rewrite.url4doc(doc._id, doc.type); - if (newURL.body == undefined) { - // If it's a url string, throw a redirect error - throw { code : 301, headers : { "Location" : newURL } }; - } else { - // If it's a {code: 404} block, throw it straight - throw newURL; - } - } else { - return null; - } - } - - return rewrite; - }; - }}} - - So the cool thing here is the 'throw' statements, if we're totally in the wrong place, I want to get out ASAP. -