本来在 HTML 中可以直接调用后端的 url_for 的,比如:
<script>
var url = "{{ url_for('site.index') }}";
</script>
不过如果是外部引用的 js 的话,就没办法(除非以 HTML data 属性作为中介进行传递,但略麻烦),所以就写了个前端的 urlFor,和后端的 url_for 对应。
首先在后端加入这一段代码:
rules = {}
for endpoint, _rules in iteritems(app.url_map._rules_by_endpoint):
if any(item in endpoint for item in ['_debug_toolbar', 'debugtoolbar', 'static']):
continue
rules[endpoint] = [{'rule': rule.rule} for rule in _rules]
app.jinja_env.globals.update({
'rules': rules,
})
然后在前端加入以下代码:
// Find out params in routing rules
var pattern = new RegExp("<[^:]*:?([^>]+)>", "g");
var result = null;
$.each(g.rules, function (endpoint, rules) {
$.each(rules, function (index, rule) {
rule.params = [];
while ((result = pattern.exec(rule.rule)) !== null) {
rule.params.push(result[1]);
}
});
});
/**
* Check whether str ends with suffix.
* @param str
* @param suffix
* @returns {boolean}
*/
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
/**
* Generate url for the endpoint.
* urlFor(endpoint [, parameters])
* @param endpoint
* @param parameters
* @returns url for the endpoint.
*/
function urlFor(endpoint, parameters) {
var url = null,
params = [],
maxMatchDegree = 0.0,
keys;
parameters = ($.type(parameters) !== 'undefined') ? parameters : {};
if (g.rules[endpoint] === undefined) {
throw new Error("Uncorrect endpoint in " + "urlFor(\"" + endpoint + "\", " +
JSON.stringify(parameters) + ")");
}
keys = $.map(parameters, function (value, key) {
return key;
});
// Find the first matched rule among rules in this endpoint.
$.each(g.rules[endpoint], function (index, rule) {
var match = true,
currentMatchDegree = 0.0;
$.each(rule.params, function (index, param) {
if ($.inArray(param, keys) === -1) {
match = false;
return false;
}
});
if (match) {
currentMatchDegree = parseFloat(rule.params.length) / keys.length;
if (currentMatchDegree > maxMatchDegree || url === null) {
maxMatchDegree = currentMatchDegree;
url = rule.rule;
params = rule.params;
}
}
});
if (url) {
$.each(keys, function (index, key) {
// Build in params
if ($.inArray(key, params) > -1) {
url = url.replace(new RegExp("<[^:]*:?" + key + ">"), parameters[key]);
} else {
// Query string params
if (url.indexOf("?") === -1) {
url += "?";
}
if (!endsWith(url, '?')) {
url += "&";
}
url += key + "=" + parameters[key];
}
});
} else {
throw new Error("Uncorrect parameters in urlFor(\"" + endpoint + "\", " +
JSON.stringify(parameters) + ")");
}
return url;
}
使用方法:
url_for('site.index') → '/'
url_for('user.view', {uid: 1}) → '/user/1'
url_for('user.view', {uid: 1, other:'other'}) → '/user/1?other=other'
url_for('user.view', {other: 'other'}) → Uncorrect parameters in urlFor("user.view", {other:'other'})
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.