Skip to content

Instantly share code, notes, and snippets.

@darkwing
Created January 11, 2013 19:52
Show Gist options
  • Save darkwing/4513464 to your computer and use it in GitHub Desktop.
Save darkwing/4513464 to your computer and use it in GitHub Desktop.
<% var wiki = module.exports = buildAPI({
/*
* Given a MediaWiki path attempt to update it to a Kuma path
* This is not a DekiScript function
*/
kumaPath: function(in_path) {
// Strip the base path, allows this to replace Template:getRelativeURL
path_strip = in_path.replace(RegExp('^https:\/\/developer\.mozilla\.org','i'),'');
// Get/fix/update/add language
var pathLang = (path_strip.match(/^\/?(\w{2}(?:[-|_]\w{2})?)?(?=\/)/)[1] || env.locale).replace(/^en$/i,'en-US').replace(/^(?:zh_)?cn$/i,'zh-CN').replace(/zh_tw/i,'zh-TW').replace(/^pt$/i,'pt-PT');
// Add fixed language and make sure there is docs and convert spaces to underscore
var path = '/' + pathLang + path_strip.replace(/^(\/?\w{2}(?:[-|_]\w{2})?)?\/(?:docs\/)?/i,'/docs/').replace(/ /g,'_').replace(/%20/g,'_');
return path;
},
// Given a path, attempt to construct an absolute URL to the wiki.
// This is not a DekiScript function, but it's used by many of those below.
buildAbsoluteURL: function (path) {
var p = kuma.url.parse(env.url, true);
var base_url = p.protocol + '//' + p.host;
if (path.indexOf('/docs') == -1) {
// HACK: If this looks like a legacy wiki URL, throw /en-US/docs
// in front of it. That will trigger the proper redirection logic
// until/unless URLs are corrected in templates
base_url += '/en-US/docs';
}
var re1 = / /gi;
var re2 = /%20/gi;
path = path.replace(re1, "_");
path = path.replace(re2, "_");
if (path.charAt(0) != '/') { base_url += '/'; }
return base_url + path;
},
// Check if the given wiki page exists.
// [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.PageExists)
pageExists: function (path) {
// Temporarily disabling this.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=775590#c4
return true;
var key = 'kuma:page_exists:' + md5(path.toLowerCase());
// This is an experiment to exempt wiki.pageExists
// from shift-refresh cache busting:
var mdn = require('MDN:Common');
//return cacheFn(key, 3600, function (next) {
return mdn.cacheFnIgnoreCacheControl(key, 3600, function (next) {
var opts = { method: 'HEAD', url: wiki.buildAbsoluteURL(path) };
try {
request(opts, function (err, resp, body) {
var result = false;
if (resp && 200 == resp.statusCode) {
result = true;
}
next(result);
});
} catch (e) {
next(false);
}
});
},
// Adjusts the visibility and heading levels of the specified HTML.
//
// The show parameter indicates whether or not the top level heading/title
// should be displayed. The heading parameter sets the heading level of the
// top level of the text to the specified value and adjusts all subsequent
// headings accordingly. This adjustment happens regardless of the value of
// show.
//
// heading is not supported at this time
_adjustHeadings: function(html, show, heading) {
if (show) { return html; }
// Rip out the first header we find
if (html) { html = html.replace(/^<(H|h)\d[^>]*>[^<]*(<\/B\d>|<\/h\d>)/ig,"") + ""; }
return html;
},
// Retrieve the content of a document for inclusion, optionally filtering
// for a single section.
//
// Doesn't (yet?) support all the parameters offered by DekiScript,
// but I don't think MDN pages use them all. Missing in particular:
// revision, show, and heading
//
// [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Page)
page: function (path, section, revision, show, heading) {
var key = 'kuma:include:' + md5(path.toLowerCase());
return cacheFn(key, 3600, function (next) {
var params = ['raw=1', 'macros=1', 'include=1'];
if (section) { params.push('section='+encodeURIComponent(section)); }
var opts = {
method: 'GET',
headers: { 'Cache-Control': env.cache_control },
url: wiki.buildAbsoluteURL(path) + '?' + params.join('&')
};
try {
request(opts, function (err, resp, body) {
var result = '';
if (resp && 200 == resp.statusCode) {
result = body || '';
if (show == undefined) {
show = 0;
}
result = wiki._adjustHeadings(result, show, heading);
}
next(result);
});
} catch (e) {
next('');
}
});
},
// http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.GetPage
getPage: function (path) {
var key = 'kuma:get_page:' + md5(path.toLowerCase());
return cacheFn(key, 3600, function (next) {
var opts = {
method: 'GET',
headers: { 'Cache-Control': env.cache_control },
url: wiki.buildAbsoluteURL(path) + "$json"
};
try {
request(opts, function (err, resp, body) {
var result = {};
if (resp && 200 == resp.statusCode) {
result = JSON.parse(body);
}
next(result);
});
} catch (e) {
next({});
}
});
},
// Retrieve the full uri of a given wiki page.
// [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Uri)
uri: function (path, query) {
var out = wiki.buildAbsoluteURL(path);
if (query) { out += '?' + query; }
return out;
},
// A link to the wiki page that you will add, that will be in a different language.
// [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Languages)
languages: function (langs) {
// TODO
var out = [];
_.each(langs, function (url, lang) {
out.push('<li><a href="', kuma.htmlEscape(url), '">',
kuma.htmlEscape(lang), '</a></li>');
});
return "<ul>" + out.join('') + "<\/ul>";
},
// Inserts a pages sub tree
// [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Tree)
tree: function(path, depth, self) {
var page = require('DekiScript:Page');
var pages = page.subpages(path, depth, self);
return process_array(pages);
function process_array(arr) {
var result = '';
if(arr.length) {
result += '<ul>';
arr.forEach(function(item) {
result += '<li><a href="' + item.url + '">' + kuma.htmlEscape(item.title) + '</a>' +
process_array(item.subpages || []) + '</li>';
});
result += '</ul>';
}
return result;
}
},
toc: function(path) {
var key = 'kuma:get_page_toc:' + md5(path.toLowerCase());
return cacheFn(key, 3600, function (next) {
var opts = {
method: 'GET',
headers: { 'Cache-Control': env.cache_control },
url: wiki.buildAbsoluteURL(path) + "?toc"
};
try {
request(opts, function (err, resp, body) {
var result = '';
if (resp && 200 == resp.statusCode) {
result = body;
}
next(result);
});
} catch (e) {
next('');
}
});
}
}); %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment