Merge pull request #469 from wojciechka/master

Support for running discourse with a prefix (i.e. as http://servername/discourse)
This commit is contained in:
Robin Ward 2013-03-18 07:24:11 -07:00
commit e1e1bdd0b1
61 changed files with 231 additions and 163 deletions

View file

@ -26,7 +26,7 @@ Discourse.AdminEmailLogsController = Ember.ArrayController.extend(Discourse.Pres
var _this = this; var _this = this;
_this.set('sentTestEmail', false); _this.set('sentTestEmail', false);
$.ajax({ $.ajax({
url: '/admin/email_logs/test', url: Discourse.getURL("/admin/email_logs/test"),
type: 'POST', type: 'POST',
data: { email_address: this.get('testEmailAddress') }, data: { email_address: this.get('testEmailAddress') },
success: function() { success: function() {

View file

@ -7,10 +7,18 @@
@module Discourse @module Discourse
**/ **/
Discourse.AdminUser = Discourse.Model.extend({ Discourse.AdminUser = Discourse.Model.extend({
path: (function() {
return Discourse.getURL("/users/") + (this.get('username_lower'));
}).property('username'),
adminPath: (function() {
return Discourse.getURL("/admin/users/") + (this.get('username_lower'));
}).property('username'),
deleteAllPosts: function() { deleteAllPosts: function() {
this.set('can_delete_all_posts', false); this.set('can_delete_all_posts', false);
$.ajax("/admin/users/" + (this.get('id')) + "/delete_all_posts", {type: 'PUT'}); $.ajax(Discourse.getURL("/admin/users/") + (this.get('id')) + "/delete_all_posts", {type: 'PUT'});
}, },
// Revoke the user's admin access // Revoke the user's admin access
@ -18,14 +26,14 @@ Discourse.AdminUser = Discourse.Model.extend({
this.set('admin', false); this.set('admin', false);
this.set('can_grant_admin', true); this.set('can_grant_admin', true);
this.set('can_revoke_admin', false); this.set('can_revoke_admin', false);
return $.ajax("/admin/users/" + (this.get('id')) + "/revoke_admin", {type: 'PUT'}); return $.ajax(Discourse.getURL("/admin/users/") + (this.get('id')) + "/revoke_admin", {type: 'PUT'});
}, },
grantAdmin: function() { grantAdmin: function() {
this.set('admin', true); this.set('admin', true);
this.set('can_grant_admin', false); this.set('can_grant_admin', false);
this.set('can_revoke_admin', true); this.set('can_revoke_admin', true);
$.ajax("/admin/users/" + (this.get('id')) + "/grant_admin", {type: 'PUT'}); $.ajax(Discourse.getURL("/admin/users/") + (this.get('id')) + "/grant_admin", {type: 'PUT'});
}, },
// Revoke the user's moderation access // Revoke the user's moderation access
@ -33,18 +41,18 @@ Discourse.AdminUser = Discourse.Model.extend({
this.set('moderator', false); this.set('moderator', false);
this.set('can_grant_moderation', true); this.set('can_grant_moderation', true);
this.set('can_revoke_moderation', false); this.set('can_revoke_moderation', false);
return $.ajax("/admin/users/" + (this.get('id')) + "/revoke_moderation", {type: 'PUT'}); return $.ajax(Discourse.getURL("/admin/users/") + (this.get('id')) + "/revoke_moderation", {type: 'PUT'});
}, },
grantModeration: function() { grantModeration: function() {
this.set('moderator', true); this.set('moderator', true);
this.set('can_grant_moderation', false); this.set('can_grant_moderation', false);
this.set('can_revoke_moderation', true); this.set('can_revoke_moderation', true);
$.ajax("/admin/users/" + (this.get('id')) + "/grant_moderation", {type: 'PUT'}); $.ajax(Discourse.getURL("/admin/users/") + (this.get('id')) + "/grant_moderation", {type: 'PUT'});
}, },
refreshBrowsers: function() { refreshBrowsers: function() {
$.ajax("/admin/users/" + (this.get('id')) + "/refresh_browsers", {type: 'POST'}); $.ajax(Discourse.getURL("/admin/users/") + (this.get('id')) + "/refresh_browsers", {type: 'POST'});
bootbox.alert("Message sent to all clients!"); bootbox.alert("Message sent to all clients!");
}, },
@ -52,7 +60,7 @@ Discourse.AdminUser = Discourse.Model.extend({
this.set('can_approve', false); this.set('can_approve', false);
this.set('approved', true); this.set('approved', true);
this.set('approved_by', Discourse.get('currentUser')); this.set('approved_by', Discourse.get('currentUser'));
$.ajax("/admin/users/" + (this.get('id')) + "/approve", {type: 'PUT'}); $.ajax(Discourse.getURL("/admin/users/") + (this.get('id')) + "/approve", {type: 'PUT'});
}, },
username_lower: (function() { username_lower: (function() {
@ -79,7 +87,7 @@ Discourse.AdminUser = Discourse.Model.extend({
_this = this; _this = this;
if (duration = parseInt(window.prompt(Em.String.i18n('admin.user.ban_duration')), 10)) { if (duration = parseInt(window.prompt(Em.String.i18n('admin.user.ban_duration')), 10)) {
if (duration > 0) { if (duration > 0) {
return $.ajax("/admin/users/" + this.id + "/ban", { return $.ajax(Discourse.getURL("/admin/users/") + this.id + "/ban", {
type: 'PUT', type: 'PUT',
data: {duration: duration}, data: {duration: duration},
success: function() { success: function() {
@ -99,7 +107,7 @@ Discourse.AdminUser = Discourse.Model.extend({
unban: function() { unban: function() {
var _this = this; var _this = this;
return $.ajax("/admin/users/" + this.id + "/unban", { return $.ajax(Discourse.getURL("/admin/users/") + this.id + "/unban", {
type: 'PUT', type: 'PUT',
success: function() { success: function() {
window.location.reload(); window.location.reload();
@ -116,7 +124,7 @@ Discourse.AdminUser = Discourse.Model.extend({
impersonate: function() { impersonate: function() {
var _this = this; var _this = this;
return $.ajax("/admin/impersonate", { return $.ajax(Discourse.getURL("/admin/impersonate"), {
type: 'POST', type: 'POST',
data: { data: {
username_or_email: this.get('username') username_or_email: this.get('username')
@ -145,7 +153,7 @@ Discourse.AdminUser.reopenClass({
user.set('can_approve', false); user.set('can_approve', false);
return user.set('selected', false); return user.set('selected', false);
}); });
return $.ajax("/admin/users/approve-bulk", { return $.ajax(Discourse.getURL("/admin/users/approve-bulk"), {
type: 'PUT', type: 'PUT',
data: { data: {
users: users.map(function(u) { users: users.map(function(u) {
@ -156,7 +164,7 @@ Discourse.AdminUser.reopenClass({
}, },
find: function(username) { find: function(username) {
return $.ajax({url: "/admin/users/" + username}).then(function (result) { return $.ajax({url: Discourse.getURL("/admin/users/") + username}).then(function (result) {
return Discourse.AdminUser.create(result); return Discourse.AdminUser.create(result);
}) })
}, },
@ -165,7 +173,7 @@ Discourse.AdminUser.reopenClass({
var result; var result;
result = Em.A(); result = Em.A();
$.ajax({ $.ajax({
url: "/admin/users/list/" + query + ".json", url: Discourse.getURL("/admin/users/list/") + query + ".json",
data: { data: {
filter: filter filter: filter
}, },

View file

@ -20,7 +20,7 @@ Discourse.EmailLog.reopenClass({
var result; var result;
result = Em.A(); result = Em.A();
$.ajax({ $.ajax({
url: "/admin/email_logs.json", url: Discourse.getURL("/admin/email_logs.json"),
data: { filter: filter }, data: { filter: filter },
success: function(logs) { success: function(logs) {
logs.each(function(log) { logs.each(function(log) {

View file

@ -47,14 +47,14 @@ Discourse.FlaggedPost = Discourse.Post.extend({
deletePost: function() { deletePost: function() {
if (this.get('post_number') === "1") { if (this.get('post_number') === "1") {
return $.ajax("/t/" + this.topic_id, { type: 'DELETE', cache: false }); return $.ajax(Discourse.getURL("/t/") + this.topic_id, { type: 'DELETE', cache: false });
} else { } else {
return $.ajax("/posts/" + this.id, { type: 'DELETE', cache: false }); return $.ajax(Discourse.getURL("/posts/") + this.id, { type: 'DELETE', cache: false });
} }
}, },
clearFlags: function() { clearFlags: function() {
return $.ajax("/admin/flags/clear/" + this.id, { type: 'POST', cache: false }); return $.ajax(Discourse.getURL("/admin/flags/clear/") + this.id, { type: 'POST', cache: false });
}, },
hiddenClass: (function() { hiddenClass: (function() {
@ -68,7 +68,7 @@ Discourse.FlaggedPost.reopenClass({
var result; var result;
result = Em.A(); result = Em.A();
$.ajax({ $.ajax({
url: "/admin/flags/" + filter + ".json", url: Discourse.getURL("/admin/flags/") + filter + ".json",
success: function(data) { success: function(data) {
var userLookup; var userLookup;
userLookup = {}; userLookup = {};

View file

@ -3,7 +3,7 @@ Discourse.Report = Discourse.Model.extend({});
Discourse.Report.reopenClass({ Discourse.Report.reopenClass({
find: function(type) { find: function(type) {
var model = Discourse.Report.create({type: type}); var model = Discourse.Report.create({type: type});
$.ajax("/admin/reports/" + type, { $.ajax(Discourse.getURL("/admin/reports/") + type, {
type: 'GET', type: 'GET',
success: function(json) { success: function(json) {

View file

@ -56,7 +56,7 @@ Discourse.SiteCustomization = Discourse.Model.extend({
override_default_style: this.override_default_style override_default_style: this.override_default_style
}; };
return $.ajax({ return $.ajax({
url: "/admin/site_customizations" + (this.id ? '/' + this.id : ''), url: Discourse.getURL("/admin/site_customizations") + (this.id ? '/' + this.id : ''),
data: { data: {
site_customization: data site_customization: data
}, },
@ -68,7 +68,7 @@ Discourse.SiteCustomization = Discourse.Model.extend({
if (!this.id) return; if (!this.id) return;
return $.ajax({ return $.ajax({
url: "/admin/site_customizations/" + this.id, url: Discourse.getURL("/admin/site_customizations/") + this.id,
type: 'DELETE' type: 'DELETE'
}); });
} }
@ -94,7 +94,7 @@ Discourse.SiteCustomization.reopenClass({
loading: true loading: true
}); });
$.ajax({ $.ajax({
url: "/admin/site_customizations", url: Discourse.getURL("/admin/site_customizations"),
dataType: "json", dataType: "json",
success: function(data) { success: function(data) {
if (data) { if (data) {

View file

@ -72,7 +72,7 @@ Discourse.SiteSetting = Discourse.Model.extend({
save: function() { save: function() {
// Update the setting // Update the setting
var setting = this; var setting = this;
return $.ajax("/admin/site_settings/" + (this.get('setting')), { return $.ajax(Discourse.getURL("/admin/site_settings/") + (this.get('setting')), {
data: { value: this.get('value') }, data: { value: this.get('value') },
type: 'PUT', type: 'PUT',
success: function() { success: function() {
@ -91,7 +91,7 @@ Discourse.SiteSetting.reopenClass({
**/ **/
findAll: function() { findAll: function() {
var result = Em.A(); var result = Em.A();
$.get("/admin/site_settings", function(settings) { $.get(Discourse.getURL("/admin/site_settings"), function(settings) {
return settings.each(function(s) { return settings.each(function(s) {
s.originalValue = s.value; s.originalValue = s.value;
return result.pushObject(Discourse.SiteSetting.create(s)); return result.pushObject(Discourse.SiteSetting.create(s));

View file

@ -26,7 +26,7 @@ Discourse.VersionCheck = Discourse.Model.extend({
Discourse.VersionCheck.reopenClass({ Discourse.VersionCheck.reopenClass({
find: function() { find: function() {
return $.ajax({ url: '/admin/version_check', dataType: 'json' }).then(function(json) { return $.ajax({ url: Discourse.getURL('/admin/version_check'), dataType: 'json' }).then(function(json) {
return Discourse.VersionCheck.create(json); return Discourse.VersionCheck.create(json);
}); });
} }

View file

@ -22,8 +22,8 @@
<td>{{date view.content.created_at}}</td> <td>{{date view.content.created_at}}</td>
<td> <td>
{{#if view.content.user}} {{#if view.content.user}}
<a href="/admin/users/{{unbound view.content.user.username_lower}}">{{avatar view.content.user imageSize="tiny"}}</a> <a href="{{unbound view.content.user.adminPath}}">{{avatar view.content.user imageSize="tiny"}}</a>
<a href="/admin/users/{{unbound view.content.user.username_lower}}">{{view.content.user.username}}</a> <a href="{{unbound view.content.user.adminPath}}">{{view.content.user.username}}</a>
{{else}} {{else}}
&mdash; &mdash;
{{/if}} {{/if}}

View file

@ -5,7 +5,7 @@
<div class='field'>{{i18n user.username.title}}</div> <div class='field'>{{i18n user.username.title}}</div>
<div class='value'>{{content.username}}</div> <div class='value'>{{content.username}}</div>
<div class='controls'> <div class='controls'>
<a href="/users/{{unbound content.username_lower}}" class='btn'> <a href="{{unbound content.path}}" class='btn'>
<i class='icon icon-user'></i> <i class='icon icon-user'></i>
{{i18n admin.user.show_public_profile}} {{i18n admin.user.show_public_profile}}
</a> </a>
@ -45,8 +45,8 @@
<div class='value'> <div class='value'>
{{#if content.approved}} {{#if content.approved}}
{{i18n admin.user.approved_by}} {{i18n admin.user.approved_by}}
<a href="/admin/users/{{unbound content.approved_by.username_lower}}">{{avatar approved_by imageSize="small"}}</a> <a href="{{unbound content.approved_by.adminPath}}">{{avatar approved_by imageSize="small"}}</a>
<a href="/admin/users/{{unbound username_lower}}">{{content.approved_by.username}}</a> <a href="{{unbound adminPath}}">{{content.approved_by.username}}</a>
{{else}} {{else}}
{{i18n no_value}} {{i18n no_value}}
{{/if}} {{/if}}

View file

@ -51,9 +51,9 @@
</td> </td>
{{/if}} {{/if}}
<td> <td>
<a href="/admin/users/{{unbound username_lower}}">{{avatar this imageSize="small"}}</a> <a href="{{unbound adminPath}}">{{avatar this imageSize="small"}}</a>
</td> </td>
<td><a href="/admin/users/{{unbound username_lower}}">{{unbound username}}</a></td> <td><a href="{{unbound adminPath}}">{{unbound username}}</a></td>
<td>{{shorten email}}</td> <td>{{shorten email}}</td>
<td>{{{unbound last_emailed_age}}}</td> <td>{{{unbound last_emailed_age}}}</td>
<td>{{{unbound last_seen_age}}}</td> <td>{{{unbound last_seen_age}}}</td>

View file

@ -22,6 +22,16 @@ Discourse = Ember.Application.createWithMixins({
// The highest seen post number by topic // The highest seen post number by topic
highestSeenByTopic: {}, highestSeenByTopic: {},
rootURL: '/',
getURL: function(url) {
var u = this.get('rootURL');
if (u[u.length-1] === '/') {
u = u.substring(0, u.length-1);
}
return u + url;
},
titleChanged: function() { titleChanged: function() {
var title; var title;
title = ""; title = "";
@ -156,7 +166,7 @@ Discourse = Ember.Application.createWithMixins({
**/ **/
logout: function() { logout: function() {
Discourse.KeyValueStore.abandonLocal(); Discourse.KeyValueStore.abandonLocal();
return $.ajax("/session/" + this.get('currentUser.username'), { return $.ajax(Discourse.getURL("/session/") + this.get('currentUser.username'), {
type: 'DELETE', type: 'DELETE',
success: function(result) { success: function(result) {
// To keep lots of our variables unbound, we can handle a redirect on logging out. // To keep lots of our variables unbound, we can handle a redirect on logging out.

View file

@ -44,7 +44,7 @@ Discourse.ClickTrack = {
ownLink = userId && (userId === Discourse.get('currentUser.id')); ownLink = userId && (userId === Discourse.get('currentUser.id'));
// Build a Redirect URL // Build a Redirect URL
trackingUrl = "/clicks/track?url=" + encodeURIComponent(href); trackingUrl = Discourse.getURL("/clicks/track?url=" + encodeURIComponent(href));
if (postId && (!$a.data('ignore-post-id'))) { if (postId && (!$a.data('ignore-post-id'))) {
trackingUrl += "&post_id=" + encodeURI(postId); trackingUrl += "&post_id=" + encodeURI(postId);
} }
@ -70,7 +70,7 @@ Discourse.ClickTrack = {
// if they want to open in a new tab, do an AJAX request // if they want to open in a new tab, do an AJAX request
if (e.metaKey || e.ctrlKey || e.which === 2) { if (e.metaKey || e.ctrlKey || e.which === 2) {
$.get("/clicks/track", { $.get(Discourse.getURL("/clicks/track"), {
url: href, url: href,
post_id: postId, post_id: postId,
topic_id: topicId, topic_id: topicId,
@ -82,7 +82,7 @@ Discourse.ClickTrack = {
// If we're on the same site, use the router and track via AJAX // If we're on the same site, use the router and track via AJAX
if (href.indexOf(window.location.origin) === 0) { if (href.indexOf(window.location.origin) === 0) {
$.get("/clicks/track", { $.get(Discourse.getURL("/clicks/track"), {
url: href, url: href,
post_id: postId, post_id: postId,
topic_id: topicId, topic_id: topicId,

View file

@ -141,7 +141,7 @@ Discourse.Markdown = {
// Add @mentions of names // Add @mentions of names
text = text.replace(/([\s\t>,:'|";\]])(@[A-Za-z0-9_-|\.]*[A-Za-z0-9_-|]+)(?=[\s\t<\!:|;',"\?\.])/g, function(x, pre, name) { text = text.replace(/([\s\t>,:'|";\]])(@[A-Za-z0-9_-|\.]*[A-Za-z0-9_-|]+)(?=[\s\t<\!:|;',"\?\.])/g, function(x, pre, name) {
if (mentionLookup(name.substr(1))) { if (mentionLookup(name.substr(1))) {
return pre + "<a href='/users/" + (name.substr(1).toLowerCase()) + "' class='mention'>" + name + "</a>"; return pre + "<a href='" + Discourse.getURL("/users/") + (name.substr(1).toLowerCase()) + "' class='mention'>" + name + "</a>";
} else { } else {
return pre + "<span class='mention'>" + name + "</span>"; return pre + "<span class='mention'>" + name + "</span>";
} }

View file

@ -21,7 +21,7 @@ Discourse.Mention = (function() {
callback(cached); callback(cached);
return false; return false;
} else { } else {
$.get("/users/is_local_username", { $.get(Discourse.getURL("/users/is_local_username"), {
username: name username: name
}, function(r) { }, function(r) {
cache(name, r.valid); cache(name, r.valid);
@ -40,7 +40,7 @@ Discourse.Mention = (function() {
username = username.substr(1); username = username.substr(1);
loading = lookup(username, function(valid) { loading = lookup(username, function(valid) {
if (valid) { if (valid) {
return $elem.replaceWith("<a href='/users/" + (username.toLowerCase()) + "' class='mention'>@" + username + "</a>"); return $elem.replaceWith("<a href='" + Discourse.getURL("/users/") + (username.toLowerCase()) + "' class='mention'>@" + username + "</a>");
} else { } else {
return $elem.removeClass('mention-loading').addClass('mention-tested'); return $elem.removeClass('mention-loading').addClass('mention-tested');
} }

View file

@ -68,7 +68,7 @@ Discourse.MessageBus = (function() {
data[c.channel] = c.last_id === void 0 ? -1 : c.last_id; data[c.channel] = c.last_id === void 0 ? -1 : c.last_id;
}); });
gotData = false; gotData = false;
_this.longPoll = $.ajax("/message-bus/" + clientId + "/poll?" + (isHidden() || !_this.enableLongPolling ? "dlp=t" : ""), { _this.longPoll = $.ajax(Discourse.getURL("/message-bus/") + clientId + "/poll?" + (isHidden() || !_this.enableLongPolling ? "dlp=t" : ""), {
data: data, data: data,
cache: false, cache: false,
dataType: 'json', dataType: 'json',

View file

@ -98,7 +98,7 @@ Discourse.ScreenTrack = Ember.Object.extend({
highestSeenByTopic[topicId] = this.highestSeen; highestSeenByTopic[topicId] = this.highestSeen;
} }
if (!Object.isEmpty(newTimings)) { if (!Object.isEmpty(newTimings)) {
$.ajax('/topics/timings', { $.ajax(Discourse.getURL('/topics/timings'), {
data: { data: {
timings: newTimings, timings: newTimings,
topic_time: this.topicTime, topic_time: this.topicTime,

View file

@ -13,6 +13,14 @@ Discourse.URL = {
// Used for matching a /more URL // Used for matching a /more URL
MORE_REGEXP: /\/more$/, MORE_REGEXP: /\/more$/,
/**
Will be pre-pended to path upon state change
@property rootURL
@default '/'
*/
rootURL: '/',
/** /**
@private @private
@ -61,6 +69,13 @@ Discourse.URL = {
routeTo: function(path) { routeTo: function(path) {
var oldPath = window.location.pathname; var oldPath = window.location.pathname;
path = path.replace(/https?\:\/\/[^\/]+/, ''); path = path.replace(/https?\:\/\/[^\/]+/, '');
/*
If the URL is absolute, remove rootURL
*/
if (path.match(/^\//)) {
var rootURL = this.rootURL.replace(/\/$/, '');
path = path.replace(rootURL, '');
}
/* /*
If the URL is in the topic form, /t/something/:topic_id/:post_number If the URL is in the topic form, /t/something/:topic_id/:post_number

View file

@ -15,7 +15,7 @@ cacheTime = null;
doSearch = function(term, topicId, success) { doSearch = function(term, topicId, success) {
return $.ajax({ return $.ajax({
url: '/users/search/users', url: Discourse.getURL('/users/search/users'),
dataType: 'JSON', dataType: 'JSON',
data: { data: {
term: term, term: term,

View file

@ -48,7 +48,7 @@ Discourse.Utilities = {
description = Em.get(category, 'description'); description = Em.get(category, 'description');
// Build the HTML link // Build the HTML link
result = "<a href=\"/category/" + this.categoryUrlId(category) + "\" class=\"badge-category\" "; result = "<a href=\"" + Discourse.getURL("/category/") + this.categoryUrlId(category) + "\" class=\"badge-category\" ";
// Add description if we have it // Add description if we have it
if (description) result += "title=\"" + description + "\" "; if (description) result += "title=\"" + description + "\" ";
@ -85,7 +85,7 @@ Discourse.Utilities = {
postUrl: function(slug, topicId, postNumber) { postUrl: function(slug, topicId, postNumber) {
var url; var url;
url = "/t/"; url = Discourse.getURL("/t/");
if (slug) { if (slug) {
url += slug + "/"; url += slug + "/";
} }

View file

@ -51,7 +51,7 @@ Discourse.PreferencesUsernameController = Discourse.ObjectController.extend({
if (result) { if (result) {
_this.set('saving', true); _this.set('saving', true);
return _this.get('content').changeUsername(_this.get('newUsername')).then(function() { return _this.get('content').changeUsername(_this.get('newUsername')).then(function() {
window.location = "/users/" + (_this.get('newUsername').toLowerCase()) + "/preferences"; window.location = Discourse.getURL("/users/") + (_this.get('newUsername').toLowerCase()) + "/preferences";
}, function() { }, function() {
/* Error /* Error
*/ */

View file

@ -23,7 +23,7 @@ Discourse.StaticController = Discourse.Controller.extend({
return this.set('content', text); return this.set('content', text);
} else { } else {
return $.ajax({ return $.ajax({
url: "" + path + ".json", url: Discourse.getURL("" + path + ".json"),
success: function(result) { success: function(result) {
return _this.set('content', result); return _this.set('content', result);
} }

View file

@ -53,7 +53,7 @@ Discourse.ActionSummary = Discourse.Model.extend({
// Create our post action // Create our post action
var actionSummary = this; var actionSummary = this;
return $.ajax({ return $.ajax({
url: "/post_actions", url: Discourse.getURL("/post_actions"),
type: 'POST', type: 'POST',
data: { data: {
id: this.get('post.id'), id: this.get('post.id'),
@ -72,7 +72,7 @@ Discourse.ActionSummary = Discourse.Model.extend({
// Remove our post action // Remove our post action
return $.ajax({ return $.ajax({
url: "/post_actions/" + (this.get('post.id')), url: Discourse.getURL("/post_actions/") + (this.get('post.id')),
type: 'DELETE', type: 'DELETE',
data: { data: {
post_action_type_id: this.get('id') post_action_type_id: this.get('id')
@ -83,7 +83,7 @@ Discourse.ActionSummary = Discourse.Model.extend({
clearFlags: function() { clearFlags: function() {
var _this = this; var _this = this;
return $.ajax({ return $.ajax({
url: "/post_actions/clear_flags", url: Discourse.getURL("/post_actions/clear_flags"),
type: "POST", type: "POST",
data: { data: {
post_action_type_id: this.get('id'), post_action_type_id: this.get('id'),
@ -98,7 +98,7 @@ Discourse.ActionSummary = Discourse.Model.extend({
loadUsers: function() { loadUsers: function() {
var _this = this; var _this = this;
return $.getJSON("/post_actions/users", { return $.getJSON(Discourse.getURL("/post_actions/users"), {
id: this.get('post.id'), id: this.get('post.id'),
post_action_type_id: this.get('id') post_action_type_id: this.get('id')
}, function(result) { }, function(result) {

View file

@ -9,7 +9,7 @@
Discourse.Category = Discourse.Model.extend({ Discourse.Category = Discourse.Model.extend({
url: (function() { url: (function() {
return "/category/" + (this.get('slug')); return Discourse.getURL("/category/") + (this.get('slug'));
}).property('name'), }).property('name'),
style: (function() { style: (function() {
@ -24,9 +24,9 @@ Discourse.Category = Discourse.Model.extend({
var url, var url,
_this = this; _this = this;
url = "/categories"; url = Discourse.getURL("/categories");
if (this.get('id')) { if (this.get('id')) {
url = "/categories/" + (this.get('id')); url = Discourse.getURL("/categories/") + (this.get('id'));
} }
return this.ajax(url, { return this.ajax(url, {
@ -43,7 +43,7 @@ Discourse.Category = Discourse.Model.extend({
"delete": function(callback) { "delete": function(callback) {
var _this = this; var _this = this;
return $.ajax("/categories/" + (this.get('slug')), { return $.ajax(Discourse.getURL("/categories/") + (this.get('slug')), {
type: 'DELETE', type: 'DELETE',
success: function() { success: function() {
return callback(); return callback();

View file

@ -32,7 +32,7 @@ Discourse.CategoryList.reopenClass({
list: function(filter) { list: function(filter) {
var route = this; var route = this;
return $.getJSON("/" + filter + ".json").then(function(result) { return $.getJSON(Discourse.getURL("/") + filter + ".json").then(function(result) {
var categoryList = Discourse.TopicList.create(); var categoryList = Discourse.TopicList.create();
categoryList.set('can_create_category', result.category_list.can_create_category); categoryList.set('can_create_category', result.category_list.can_create_category);
categoryList.set('categories', route.categoriesFrom(result)); categoryList.set('categories', route.categoriesFrom(result));

View file

@ -13,7 +13,7 @@ Discourse.Draft.reopenClass({
clear: function(key, sequence) { clear: function(key, sequence) {
return $.ajax({ return $.ajax({
type: 'DELETE', type: 'DELETE',
url: "/draft", url: Discourse.getURL("/draft"),
data: { data: {
draft_key: key, draft_key: key,
sequence: sequence sequence: sequence
@ -23,7 +23,7 @@ Discourse.Draft.reopenClass({
get: function(key) { get: function(key) {
return $.ajax({ return $.ajax({
url: '/draft', url: Discourse.getURL('/draft'),
data: { draft_key: key }, data: { draft_key: key },
dataType: 'json' dataType: 'json'
}); });
@ -38,7 +38,7 @@ Discourse.Draft.reopenClass({
data = typeof data === "string" ? data : JSON.stringify(data); data = typeof data === "string" ? data : JSON.stringify(data);
return $.ajax({ return $.ajax({
type: 'POST', type: 'POST',
url: "/draft", url: Discourse.getURL("/draft"),
data: { data: {
draft_key: key, draft_key: key,
data: data, data: data,

View file

@ -10,7 +10,7 @@
Discourse.Invite = Discourse.Model.extend({ Discourse.Invite = Discourse.Model.extend({
rescind: function() { rescind: function() {
$.ajax('/invites', { $.ajax(Discourse.getURL('/invites'), {
type: 'DELETE', type: 'DELETE',
data: { email: this.get('email') } data: { email: this.get('email') }
}); });

View file

@ -15,7 +15,7 @@ Discourse.InviteList = Discourse.Model.extend({
Discourse.InviteList.reopenClass({ Discourse.InviteList.reopenClass({
findInvitedBy: function(user) { findInvitedBy: function(user) {
return $.ajax({ url: "/users/" + (user.get('username_lower')) + "/invited.json" }).then(function (result) { return $.ajax({ url: Discourse.getURL("/users/") + (user.get('username_lower')) + "/invited.json" }).then(function (result) {
var invitedList = result.invited_list; var invitedList = result.invited_list;
if (invitedList.pending) { if (invitedList.pending) {
invitedList.pending = invitedList.pending.map(function(i) { invitedList.pending = invitedList.pending.map(function(i) {

View file

@ -27,9 +27,9 @@ Discourse.NavItem = Discourse.Model.extend({
var name; var name;
name = this.get('name'); name = this.get('name');
if (name === 'category') { if (name === 'category') {
return "/" + name + "/" + (this.get('categoryName')); return Discourse.getURL("/") + name + "/" + (this.get('categoryName'));
} else { } else {
return "/" + name; return Discourse.getURL("/") + name;
} }
}).property() }).property()
}); });

View file

@ -17,7 +17,7 @@ Discourse.Notification = Discourse.Model.extend({
var slug; var slug;
if (this.blank('data.topic_title')) return ""; if (this.blank('data.topic_title')) return "";
slug = this.get('slug'); slug = this.get('slug');
return "/t/" + slug + "/" + (this.get('topic_id')) + "/" + (this.get('post_number')); return Discourse.getURL("/t/") + slug + "/" + (this.get('topic_id')) + "/" + (this.get('post_number'));
}).property(), }).property(),
rendered: (function() { rendered: (function() {

View file

@ -13,9 +13,13 @@ Discourse.Post = Discourse.Model.extend({
}).property('post_number', 'topic_id', 'topic.slug'), }).property('post_number', 'topic_id', 'topic.slug'),
originalPostUrl: (function() { originalPostUrl: (function() {
return "/t/" + (this.get('topic_id')) + "/" + (this.get('reply_to_post_number')); return Discourse.getURL("/t/") + (this.get('topic_id')) + "/" + (this.get('reply_to_post_number'));
}).property('reply_to_post_number'), }).property('reply_to_post_number'),
usernameUrl: (function() {
return Discourse.getURL("/users/" + this.get('username'));
}).property('username'),
showUserReplyTab: (function() { showUserReplyTab: (function() {
return this.get('reply_to_user') && (this.get('reply_to_post_number') < (this.get('post_number') - 1)); return this.get('reply_to_user') && (this.get('reply_to_post_number') < (this.get('post_number') - 1));
}).property('reply_to_user', 'reply_to_post_number', 'post_number'), }).property('reply_to_user', 'reply_to_post_number', 'post_number'),
@ -65,7 +69,7 @@ Discourse.Post = Discourse.Model.extend({
bookmarkedChanged: (function() { bookmarkedChanged: (function() {
var _this = this; var _this = this;
return $.ajax({ return $.ajax({
url: "/posts/" + (this.get('id')) + "/bookmark", url: Discourse.getURL("/posts/") + (this.get('id')) + "/bookmark",
type: 'PUT', type: 'PUT',
data: { data: {
bookmarked: this.get('bookmarked') ? true : false bookmarked: this.get('bookmarked') ? true : false
@ -124,7 +128,7 @@ Discourse.Post = Discourse.Model.extend({
if (!this.get('newPost')) { if (!this.get('newPost')) {
// We're updating a post // We're updating a post
return $.ajax({ return $.ajax({
url: "/posts/" + (this.get('id')), url: Discourse.getURL("/posts/") + (this.get('id')),
type: 'PUT', type: 'PUT',
data: { data: {
post: { raw: this.get('raw') }, post: { raw: this.get('raw') },
@ -155,7 +159,7 @@ Discourse.Post = Discourse.Model.extend({
} }
return $.ajax({ return $.ajax({
type: 'POST', type: 'POST',
url: "/posts", url: Discourse.getURL("/posts"),
data: data, data: data,
success: function(result) { success: function(result) {
return typeof complete === "function" ? complete(Discourse.Post.create(result)) : void 0; return typeof complete === "function" ? complete(Discourse.Post.create(result)) : void 0;
@ -168,11 +172,11 @@ Discourse.Post = Discourse.Model.extend({
}, },
recover: function() { recover: function() {
return $.ajax("/posts/" + (this.get('id')) + "/recover", { type: 'PUT', cache: false }); return $.ajax(Discourse.getURL("/posts/") + (this.get('id')) + "/recover", { type: 'PUT', cache: false });
}, },
"delete": function(complete) { "delete": function(complete) {
return $.ajax("/posts/" + (this.get('id')), { return $.ajax(Discourse.getURL("/posts/") + (this.get('id')), {
type: 'DELETE', type: 'DELETE',
success: function(result) { success: function(result) {
return typeof complete === "function" ? complete() : void 0; return typeof complete === "function" ? complete() : void 0;
@ -219,7 +223,7 @@ Discourse.Post = Discourse.Model.extend({
this.set('replies', []); this.set('replies', []);
var parent = this; var parent = this;
return $.ajax({url: "/posts/" + (this.get('id')) + "/replies"}).then(function(loaded) { return $.ajax({url: Discourse.getURL("/posts/") + (this.get('id')) + "/replies"}).then(function(loaded) {
var replies = parent.get('replies'); var replies = parent.get('replies');
loaded.each(function(reply) { loaded.each(function(reply) {
var post = Discourse.Post.create(reply); var post = Discourse.Post.create(reply);
@ -231,7 +235,7 @@ Discourse.Post = Discourse.Model.extend({
}, },
loadVersions: function(callback) { loadVersions: function(callback) {
return $.get("/posts/" + (this.get('id')) + "/versions.json", function(result) { return $.get(Discourse.getURL("/posts/") + (this.get('id')) + "/versions.json", function(result) {
return callback(result); return callback(result);
}); });
}, },
@ -287,7 +291,7 @@ Discourse.Post.reopenClass({
}, },
deleteMany: function(posts) { deleteMany: function(posts) {
return $.ajax("/posts/destroy_many", { return $.ajax(Discourse.getURL("/posts/destroy_many"), {
type: 'DELETE', type: 'DELETE',
data: { data: {
post_ids: posts.map(function(p) { return p.get('id'); }) post_ids: posts.map(function(p) { return p.get('id'); })
@ -296,26 +300,26 @@ Discourse.Post.reopenClass({
}, },
loadVersion: function(postId, version, callback) { loadVersion: function(postId, version, callback) {
return $.ajax({url: "/posts/" + postId + ".json?version=" + version}).then(function(result) { return $.ajax({url: Discourse.getURL("/posts/") + postId + ".json?version=" + version}).then(function(result) {
return Discourse.Post.create(result); return Discourse.Post.create(result);
}); });
}, },
loadByPostNumber: function(topicId, postId) { loadByPostNumber: function(topicId, postId) {
return $.ajax({url: "/posts/by_number/" + topicId + "/" + postId + ".json"}).then(function (result) { return $.ajax({url: Discourse.getURL("/posts/by_number/") + topicId + "/" + postId + ".json"}).then(function (result) {
return Discourse.Post.create(result); return Discourse.Post.create(result);
}); });
}, },
loadQuote: function(postId) { loadQuote: function(postId) {
return $.ajax({url: "/posts/" + postId + ".json"}).then(function(result) { return $.ajax({url: Discourse.getURL("/posts/") + postId + ".json"}).then(function(result) {
var post = Discourse.Post.create(result); var post = Discourse.Post.create(result);
return Discourse.BBCode.buildQuoteBBCode(post, post.get('raw')); return Discourse.BBCode.buildQuoteBBCode(post, post.get('raw'));
}); });
}, },
load: function(postId) { load: function(postId) {
return $.ajax({url: "/posts/" + postId + ".json"}).then(function (result) { return $.ajax({url: Discourse.getURL("/posts/") + postId + ".json"}).then(function (result) {
return Discourse.Post.create(result); return Discourse.Post.create(result);
}); });
} }

View file

@ -42,7 +42,7 @@ Discourse.Topic = Discourse.Model.extend({
if (slug.isBlank()) { if (slug.isBlank()) {
slug = "topic"; slug = "topic";
} }
return "/t/" + slug + "/" + (this.get('id')); return Discourse.getURL("/t/") + slug + "/" + (this.get('id'));
}).property('id', 'slug'), }).property('id', 'slug'),
// Helper to build a Url with a post number // Helper to build a Url with a post number
@ -169,7 +169,7 @@ Discourse.Topic = Discourse.Model.extend({
// Reset our read data for this topic // Reset our read data for this topic
resetRead: function(callback) { resetRead: function(callback) {
return $.ajax("/t/" + (this.get('id')) + "/timings", { return $.ajax(Discourse.getURL("/t/") + (this.get('id')) + "/timings", {
type: 'DELETE', type: 'DELETE',
success: function() { success: function() {
return typeof callback === "function" ? callback() : void 0; return typeof callback === "function" ? callback() : void 0;
@ -181,7 +181,7 @@ Discourse.Topic = Discourse.Model.extend({
inviteUser: function(user) { inviteUser: function(user) {
return $.ajax({ return $.ajax({
type: 'POST', type: 'POST',
url: "/t/" + (this.get('id')) + "/invite", url: Discourse.getURL("/t/") + (this.get('id')) + "/invite",
data: { data: {
user: user user: user
} }
@ -190,7 +190,7 @@ Discourse.Topic = Discourse.Model.extend({
// Delete this topic // Delete this topic
"delete": function(callback) { "delete": function(callback) {
return $.ajax("/t/" + (this.get('id')), { return $.ajax(Discourse.getURL("/t/") + (this.get('id')), {
type: 'DELETE', type: 'DELETE',
success: function() { success: function() {
return typeof callback === "function" ? callback() : void 0; return typeof callback === "function" ? callback() : void 0;
@ -306,7 +306,7 @@ Discourse.Topic = Discourse.Model.extend({
this.set('notification_level', v); this.set('notification_level', v);
this.set('notifications_reason_id', null); this.set('notifications_reason_id', null);
return $.ajax({ return $.ajax({
url: "/t/" + (this.get('id')) + "/notifications", url: Discourse.getURL("/t/") + (this.get('id')) + "/notifications",
type: 'POST', type: 'POST',
data: { data: {
notification_level: v notification_level: v
@ -341,7 +341,7 @@ Discourse.Topic = Discourse.Model.extend({
// Clear the pin optimistically from the object // Clear the pin optimistically from the object
topic.set('pinned', false); topic.set('pinned', false);
$.ajax("/t/" + this.get('id') + "/clear-pin", { $.ajax(Discourse.getURL("/t/") + this.get('id') + "/clear-pin", {
type: 'PUT', type: 'PUT',
error: function() { error: function() {
// On error, put the pin back // On error, put the pin back
@ -391,7 +391,7 @@ Discourse.Topic.reopenClass({
// onLoad - the callback after the topic is loaded // onLoad - the callback after the topic is loaded
find: function(topicId, opts) { find: function(topicId, opts) {
var data, promise, url; var data, promise, url;
url = "/t/" + topicId; url = Discourse.getURL("/t/") + topicId;
if (opts.nearPost) { if (opts.nearPost) {
url += "/" + opts.nearPost; url += "/" + opts.nearPost;
@ -435,7 +435,7 @@ Discourse.Topic.reopenClass({
// Create a topic from posts // Create a topic from posts
movePosts: function(topicId, title, postIds) { movePosts: function(topicId, title, postIds) {
return $.ajax("/t/" + topicId + "/move-posts", { return $.ajax(Discourse.getURL(Discourse.getURL("/t/")) + topicId + "/move-posts", {
type: 'POST', type: 'POST',
data: { title: title, post_ids: postIds } data: { title: title, post_ids: postIds }
}); });

View file

@ -13,7 +13,7 @@ Discourse.TopicList = Discourse.Model.extend({
var moreUrl, _this = this; var moreUrl, _this = this;
if (moreUrl = this.get('more_topics_url')) { if (moreUrl = this.get('more_topics_url')) {
Discourse.URL.replaceState("/" + (this.get('filter')) + "/more"); Discourse.URL.replaceState(Discourse.getURL("/") + (this.get('filter')) + "/more");
return $.ajax({url: moreUrl}).then(function (result) { return $.ajax({url: moreUrl}).then(function (result) {
var newTopics, topicIds, topics, topicsAdded = 0; var newTopics, topicIds, topics, topicsAdded = 0;
if (result) { if (result) {
@ -91,7 +91,7 @@ Discourse.TopicList.reopenClass({
topic_list = Discourse.TopicList.create(); topic_list = Discourse.TopicList.create();
topic_list.set('inserted', Em.A()); topic_list.set('inserted', Em.A());
topic_list.set('filter', filter); topic_list.set('filter', filter);
url = "/" + filter + ".json"; url = Discourse.getURL("/") + filter + ".json";
if (menuItem.filters && menuItem.filters.length > 0) { if (menuItem.filters && menuItem.filters.length > 0) {
url += "?exclude_category=" + menuItem.filters[0].substring(1); url += "?exclude_category=" + menuItem.filters[0].substring(1);
} }

View file

@ -45,7 +45,17 @@ Discourse.User = Discourse.Model.extend({
@type {String} @type {String}
**/ **/
path: (function() { path: (function() {
return "/users/" + (this.get('username_lower')); return Discourse.getURL("/users/") + (this.get('username_lower'));
}).property('username'),
/**
Path to this user's administration
@property adminPath
@type {String}
**/
adminPath: (function() {
return Discourse.getURL("/admin/users/") + (this.get('username_lower'));
}).property('username'), }).property('username'),
/** /**
@ -77,7 +87,7 @@ Discourse.User = Discourse.Model.extend({
**/ **/
changeUsername: function(newUsername) { changeUsername: function(newUsername) {
return $.ajax({ return $.ajax({
url: "/users/" + (this.get('username_lower')) + "/preferences/username", url: Discourse.getURL("/users/") + (this.get('username_lower')) + "/preferences/username",
type: 'PUT', type: 'PUT',
data: { data: {
new_username: newUsername new_username: newUsername
@ -94,7 +104,7 @@ Discourse.User = Discourse.Model.extend({
**/ **/
changeEmail: function(email) { changeEmail: function(email) {
return $.ajax({ return $.ajax({
url: "/users/" + (this.get('username_lower')) + "/preferences/email", url: Discourse.getURL("/users/") + (this.get('username_lower')) + "/preferences/email",
type: 'PUT', type: 'PUT',
data: { data: {
email: email email: email
@ -121,7 +131,7 @@ Discourse.User = Discourse.Model.extend({
**/ **/
save: function(finished) { save: function(finished) {
var _this = this; var _this = this;
$.ajax("/users/" + this.get('username').toLowerCase(), { $.ajax(Discourse.getURL("/users/") + this.get('username').toLowerCase(), {
data: this.getProperties('auto_track_topics_after_msecs', data: this.getProperties('auto_track_topics_after_msecs',
'bio_raw', 'bio_raw',
'website', 'website',
@ -154,7 +164,7 @@ Discourse.User = Discourse.Model.extend({
var good; var good;
good = false; good = false;
$.ajax({ $.ajax({
url: '/session/forgot_password', url: Discourse.getURL("/session/forgot_password"),
dataType: 'json', dataType: 'json',
data: { data: {
username: this.get('username') username: this.get('username')
@ -200,7 +210,7 @@ Discourse.User = Discourse.Model.extend({
_this = this; _this = this;
stream = this.get('stream'); stream = this.get('stream');
$.ajax({ $.ajax({
url: "/user_actions/" + id + ".json", url: Discourse.getURL("/user_actions/") + id + ".json",
dataType: 'json', dataType: 'json',
cache: 'false', cache: 'false',
success: function(result) { success: function(result) {
@ -236,7 +246,7 @@ Discourse.User = Discourse.Model.extend({
stream = this.get('stream'); stream = this.get('stream');
if (!stream) return; if (!stream) return;
url = "/user_actions?offset=" + this.get('totalItems') + "&user_id=" + (this.get("id")); url = Discourse.getURL("/user_actions?offset=") + this.get('totalItems') + "&user_id=" + (this.get("id"));
if (this.get('streamFilter')) { if (this.get('streamFilter')) {
url += "&filter=" + (this.get('streamFilter')); url += "&filter=" + (this.get('streamFilter'));
} }
@ -363,7 +373,7 @@ Discourse.User.reopenClass({
**/ **/
checkUsername: function(username, email) { checkUsername: function(username, email) {
return $.ajax({ return $.ajax({
url: '/users/check_username', url: Discourse.getURL('/users/check_username'),
type: 'GET', type: 'GET',
data: { data: {
username: username, username: username,
@ -428,7 +438,7 @@ Discourse.User.reopenClass({
// Check the preload store first // Check the preload store first
return PreloadStore.get("user_" + username, function() { return PreloadStore.get("user_" + username, function() {
return $.ajax({ url: "/users/" + username + '.json' }); return $.ajax({ url: Discourse.getURL("/users/") + username + '.json' });
}).then(function (json) { }).then(function (json) {
// Create a user from the resulting JSON // Create a user from the resulting JSON
@ -466,7 +476,7 @@ Discourse.User.reopenClass({
**/ **/
createAccount: function(name, email, password, username, passwordConfirm, challenge) { createAccount: function(name, email, password, username, passwordConfirm, challenge) {
return $.ajax({ return $.ajax({
url: '/users', url: Discourse.getURL("/users"),
dataType: 'json', dataType: 'json',
data: { data: {
name: name, name: name,

View file

@ -24,7 +24,7 @@
<td class='posters'> <td class='posters'>
{{#each posters}} {{#each posters}}
<a href="/users/{{user.username_lower}}">{{avatar this usernamePath="user.username" imageSize="small"}}</a> <a href="{{user.path}}">{{avatar this usernamePath="user.username" imageSize="small"}}</a>
{{/each}} {{/each}}
</td> </td>

View file

@ -28,8 +28,8 @@
<div class='topic-meta-data span2'> <div class='topic-meta-data span2'>
<div class='contents'> <div class='contents'>
<a href='/users/{{unbound username}}'>{{avatar this imageSize="large"}}</a> <a href='{{unbound usernameUrl}}'>{{avatar this imageSize="large"}}</a>
<h3 {{bindAttr class="moderator new_user"}}><a href='/users/{{unbound username}}'>{{breakUp username}}</a></h3> <h3 {{bindAttr class="moderator new_user"}}><a href='{{unbound usernameUrl}}'>{{breakUp username}}</a></h3>
<div class='post-info'> <div class='post-info'>
<a href='#' class='post-date' {{bindAttr data-share-url="url"}}>{{date created_at}}</a> <a href='#' class='post-date' {{bindAttr data-share-url="url"}}>{{date created_at}}</a>

View file

@ -21,8 +21,8 @@
{{#each content.redeemed}} {{#each content.redeemed}}
<tr> <tr>
<td> <td>
<a href="/users/{{unbound user.username_lower}}">{{avatar user imageSize="tiny"}}</a> <a href="{{unbound user.path}}">{{avatar user imageSize="tiny"}}</a>
<a href="/users/{{unbound user.username_lower}}">{{user.username}}</a> <a href="{{unbound user.path}}">{{user.username}}</a>
</td> </td>
<td>{{date redeemed_at}}</td> <td>{{date redeemed_at}}</td>
<td>{{date user.last_seen_at}}</td> <td>{{date user.last_seen_at}}</td>

View file

@ -2,7 +2,7 @@
{{#collection contentBinding="stream" itemClass="item"}} {{#collection contentBinding="stream" itemClass="item"}}
{{#with view.content}} {{#with view.content}}
<div class='clearfix info'> <div class='clearfix info'>
<a href="/users/{{unbound username}}" class='avatar-link'><div class='avatar-wrapper'>{{avatar this imageSize="large" extraClasses="actor" ignoreTitle="true"}}</div></a> <a href="{{unbound usernameUrl}}" class='avatar-link'><div class='avatar-wrapper'>{{avatar this imageSize="large" extraClasses="actor" ignoreTitle="true"}}</div></a>
<span class='time'>{{date path="created_at" leaveAgo="true"}}</span> <span class='time'>{{date path="created_at" leaveAgo="true"}}</span>
<span class="title"> <span class="title">
<a href="{{unbound postUrl}}">{{unbound title}}</a> <a href="{{unbound postUrl}}">{{unbound title}}</a>
@ -17,7 +17,7 @@
{{/if}} {{/if}}
</span> </span>
{{/unless}} {{/unless}}
<a class='name' href="/users/{{unbound username}}">{{personalizedName name usernamePath="username"}}</a> <a class='name' href="{{unbound usernameUrl}}">{{personalizedName name usernamePath="username"}}</a>
{{#if description}} {{#if description}}
<span class='type'>{{unbound description}}</span> <span class='type'>{{unbound description}}</span>
{{#if isPostAction}} {{#if isPostAction}}
@ -40,7 +40,7 @@
<div class='child-actions'> <div class='child-actions'>
<i class="icon {{unbound icon}}"></i> <i class="icon {{unbound icon}}"></i>
{{#each items}} {{#each items}}
<a href="/users/{{unbound username}}" class='avatar-link'><div class='avatar-wrapper'>{{avatar this imageSize="tiny" extraClasses="actor" ignoreTitle="true"}}</div></a> <a href="{{unbound usernameUrl}}" class='avatar-link'><div class='avatar-wrapper'>{{avatar this imageSize="tiny" extraClasses="actor" ignoreTitle="true"}}</div></a>
{{/each}} {{/each}}
</div> </div>
{{/each}} {{/each}}

View file

@ -7,7 +7,7 @@
<button {{action "logout" target="Discourse"}} class='btn'>{{i18n user.log_out}}</button> <button {{action "logout" target="Discourse"}} class='btn'>{{i18n user.log_out}}</button>
{{/if}} {{/if}}
{{#if Discourse.currentUser.admin}} {{#if Discourse.currentUser.admin}}
<a href="/admin/users/{{unbound content.username_lower}}" class='btn'><i class="icon-wrench"></i>&nbsp;{{i18n admin.user.show_admin_profile}}</a> <a href="{{unbound content.adminPath}}" class='btn'><i class="icon-wrench"></i>&nbsp;{{i18n admin.user.show_admin_profile}}</a>
{{/if}} {{/if}}
<ul class="nav nav-pills"> <ul class="nav nav-pills">
<li> <li>

View file

@ -29,7 +29,7 @@ Discourse.ActionsHistoryView = Discourse.View.extend({
if (c.get('users')) { if (c.get('users')) {
c.get('users').forEach(function(u) { c.get('users').forEach(function(u) {
buffer.push("<a href=\"/users/" + (u.get('username_lower')) + "\">"); buffer.push("<a href=\"" + Discourse.getURL("/users/") + (u.get('username_lower')) + "\">");
buffer.push(Discourse.Utilities.avatarImg({ buffer.push(Discourse.Utilities.avatarImg({
size: 'small', size: 'small',
username: u.get('username'), username: u.get('username'),

View file

@ -53,7 +53,7 @@ Discourse.HeaderView = Discourse.View.extend({
showNotifications: function() { showNotifications: function() {
var _this = this; var _this = this;
$.get("/notifications").then(function(result) { $.get(Discourse.getURL("/notifications")).then(function(result) {
_this.set('notifications', result.map(function(n) { _this.set('notifications', result.map(function(n) {
return Discourse.Notification.create(n); return Discourse.Notification.create(n);
})); }));
@ -93,7 +93,7 @@ Discourse.HeaderView = Discourse.View.extend({
@property logoHTML @property logoHTML
**/ **/
logoHTML: function() { logoHTML: function() {
var result = "<div class='title'><a href='/'>"; var result = "<div class='title'><a href='" + Discourse.getURL("/") + "'>";
if (this.get('controller.showExtraInfo')) { if (this.get('controller.showExtraInfo')) {
var logo = Discourse.SiteSettings.logo_small_url; var logo = Discourse.SiteSettings.logo_small_url;
if (logo && logo.length > 1) { if (logo && logo.length > 1) {

View file

@ -243,7 +243,7 @@ Discourse.CreateAccountView = Discourse.ModalBodyView.extend({
fetchConfirmationValue: function() { fetchConfirmationValue: function() {
var _this = this; var _this = this;
return $.ajax({ return $.ajax({
url: '/users/hp.json', url: Discourse.getURL('/users/hp.json'),
success: function(json) { success: function(json) {
_this.set('accountPasswordConfirm', json.value); _this.set('accountPasswordConfirm', json.value);
return _this.set('accountChallenge', json.challenge.split("").reverse().join("")); return _this.set('accountChallenge', json.challenge.split("").reverse().join(""));

View file

@ -61,7 +61,7 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
saveSuccess: function(result) { saveSuccess: function(result) {
$('#discourse-modal').modal('hide'); $('#discourse-modal').modal('hide');
window.location = "/category/" + (Discourse.Utilities.categoryUrlId(result.category)); window.location = Discourse.getURL("/category/") + (Discourse.Utilities.categoryUrlId(result.category));
}, },
saveCategory: function() { saveCategory: function() {

View file

@ -16,7 +16,7 @@ Discourse.ForgotPasswordView = Discourse.ModalBodyView.extend({
}).property('accountEmailOrUsername'), }).property('accountEmailOrUsername'),
submit: function() { submit: function() {
$.post("/session/forgot_password", { $.post(Discourse.getURL("/session/forgot_password"), {
username: this.get('accountEmailOrUsername') username: this.get('accountEmailOrUsername')
}); });
// don't tell people what happened, this keeps it more secure (ensure same on server) // don't tell people what happened, this keeps it more secure (ensure same on server)

View file

@ -45,7 +45,7 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
login: function() { login: function() {
var _this = this; var _this = this;
this.set('loggingIn', true); this.set('loggingIn', true);
$.post("/session", { $.post(Discourse.getURL("/session"), {
login: this.get('loginName'), login: this.get('loginName'),
password: this.get('loginPassword') password: this.get('loginPassword')
}).success(function(result) { }).success(function(result) {
@ -82,7 +82,7 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
this.set('authenticate', 'twitter'); this.set('authenticate', 'twitter');
left = this.get('lastX') - 400; left = this.get('lastX') - 400;
top = this.get('lastY') - 200; top = this.get('lastY') - 200;
return window.open("/auth/twitter", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top); return window.open(Discourse.getURL("/auth/twitter"), "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top);
}, },
facebookLogin: function() { facebookLogin: function() {
@ -90,7 +90,7 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
this.set('authenticate', 'facebook'); this.set('authenticate', 'facebook');
left = this.get('lastX') - 400; left = this.get('lastX') - 400;
top = this.get('lastY') - 200; top = this.get('lastY') - 200;
return window.open("/auth/facebook", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top); return window.open(Discourse.getURL("/auth/facebook"), "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top);
}, },
openidLogin: function(provider) { openidLogin: function(provider) {
@ -99,9 +99,9 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
top = this.get('lastY') - 200; top = this.get('lastY') - 200;
if (provider === "yahoo") { if (provider === "yahoo") {
this.set("authenticate", 'yahoo'); this.set("authenticate", 'yahoo');
return window.open("/auth/yahoo", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top); return window.open(Discourse.getURL("/auth/yahoo"), "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top);
} else { } else {
window.open("/auth/google", "_blank", "menubar=no,status=no,height=500,width=850,left=" + left + ",top=" + top); window.open(Discourse.getURL("/auth/google"), "_blank", "menubar=no,status=no,height=500,width=850,left=" + left + ",top=" + top);
return this.set("authenticate", 'google'); return this.set("authenticate", 'google');
} }
}, },
@ -111,7 +111,7 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
this.set('authenticate', 'github'); this.set('authenticate', 'github');
left = this.get('lastX') - 400; left = this.get('lastX') - 400;
top = this.get('lastY') - 200; top = this.get('lastY') - 200;
return window.open("/auth/github", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top); return window.open(Discourse.getURL("/auth/github"), "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top);
}, },
personaLogin: function() { personaLogin: function() {

View file

@ -12,7 +12,7 @@ Discourse.NotActivatedView = Discourse.ModalBodyView.extend({
emailSent: false, emailSent: false,
sendActivationEmail: function() { sendActivationEmail: function() {
$.get('/users/' + this.get('username') + '/send_activation_email'); $.get(Discourse.getURL('/users/') + this.get('username') + '/send_activation_email');
this.set('emailSent', true); this.set('emailSent', true);
} }
}); });

View file

@ -149,7 +149,7 @@ Discourse.PostView = Discourse.View.extend({
navLink = "<a href='" + (topic.urlForPostNumber(postNumber)) + "' title='" + quoteTitle + "' class='back'></a>"; navLink = "<a href='" + (topic.urlForPostNumber(postNumber)) + "' title='" + quoteTitle + "' class='back'></a>";
} else { } else {
// Made up slug should be replaced with canonical URL // Made up slug should be replaced with canonical URL
navLink = "<a href='/t/via-quote/" + topicId + "/" + postNumber + "' title='" + quoteTitle + "' class='quote-other-topic'></a>"; navLink = "<a href='" + Discourse.getURL("/t/via-quote/") + topicId + "/" + postNumber + "' title='" + quoteTitle + "' class='quote-other-topic'></a>";
} }
} else if (topic = this.get('controller.content')) { } else if (topic = this.get('controller.content')) {
// assume the same topic // assume the same topic
@ -180,7 +180,7 @@ Discourse.PostView = Discourse.View.extend({
if ($aside.data('topic')) { if ($aside.data('topic')) {
topic_id = $aside.data('topic'); topic_id = $aside.data('topic');
} }
$.getJSON("/posts/by_number/" + topic_id + "/" + ($aside.data('post')), function(result) { $.getJSON(Discourse.getURL("/posts/by_number/") + topic_id + "/" + ($aside.data('post')), function(result) {
var parsed = $(result.cooked); var parsed = $(result.cooked);
parsed.replaceText(originalText, "<span class='highlighted'>" + originalText + "</span>"); parsed.replaceText(originalText, "<span class='highlighted'>" + originalText + "</span>");
return $blockQuote.showHtml(parsed); return $blockQuote.showHtml(parsed);

View file

@ -96,7 +96,7 @@ Discourse.SearchView = Discourse.View.extend({
} }
this.searcher = this.searcher || Discourse.debounce(function(term, typeFilter) { this.searcher = this.searcher || Discourse.debounce(function(term, typeFilter) {
_this.currentSearch = $.ajax({ _this.currentSearch = $.ajax({
url: '/search', url: Discourse.getURL('/search'),
data: { data: {
term: term, term: term,
type_filter: typeFilter type_filter: typeFilter

View file

@ -487,7 +487,7 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
opts.catLink = Discourse.Utilities.categoryLink(category); opts.catLink = Discourse.Utilities.categoryLink(category);
return Ember.String.i18n("topic.read_more_in_category", opts); return Ember.String.i18n("topic.read_more_in_category", opts);
} else { } else {
opts.catLink = "<a href=\"/categories\">" + (Em.String.i18n("topic.browse_all_categories")) + "</a>"; opts.catLink = "<a href=\"" + Discourse.getURL("/categories") + "\">" + (Em.String.i18n("topic.browse_all_categories")) + "</a>";
return Ember.String.i18n("topic.read_more", opts); return Ember.String.i18n("topic.read_more", opts);
} }
}).property(), }).property(),

View file

@ -19,7 +19,7 @@ class InvitesController < ApplicationController
topic = invite.topics.first topic = invite.topics.first
if topic.present? if topic.present?
redirect_to topic.relative_url redirect_to "#{Discourse.base_uri}#{topic.relative_url}"
return return
end end
end end

View file

@ -54,4 +54,15 @@ module ApplicationHelper
result result
end end
def faq_path
return "#{Discourse::base_uri}/faq"
end
def tos_path
return "#{Discourse::base_uri}/tos"
end
def privacy_path
return "#{Discourse::base_uri}/privacy"
end
end end

View file

@ -8,7 +8,7 @@
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/auth/persona/callback', url: Discourse.getURL('/auth/persona/callback'),
data: { 'assertion': assertion }, data: { 'assertion': assertion },
success: function(data, textStatus, jqXHR) { success: function(data, textStatus, jqXHR) {
Discourse.authenticationComplete(data); Discourse.authenticationComplete(data);

View file

@ -21,9 +21,9 @@
@font-face { @font-face {
font-family: 'zocial'; font-family: 'zocial';
src: url('/assets/zocial-regular-webfont.woff?<%= font_domain %>') format('woff'), src: url('<%=asset_path "zocial-regular-webfont.woff" %>?<%= font_domain %>') format('woff'),
url('/assets/zocial-regular-webfont.ttf?<%= font_domain %>') format('truetype'), url('<%=asset_path "zocial-regular-webfont.ttf" %>?<%= font_domain %>') format('truetype'),
url('/assets/zocial-regular-webfont.svg?<%= font_domain %>#zocialregular') format('svg'); url('<%=asset_path "zocial-regular-webfont.svg" %>?<%= font_domain %>#zocialregular') format('svg');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;

View file

@ -1,7 +1,7 @@
<ul class="nav-pills"> <ul class="nav-pills">
<li><a class="active" href="/faq">FAQ</a></li> <li><a class="active" href="<%=faq_path%>">FAQ</a></li>
<li><a href="/tos">Podmínky používání</a></li> <li><a href="<%=tos_path%>">Podmínky používání</a></li>
<li><a href="/privacy">Ochrana soukromí</a></li> <li><a href="<%=privacy_path%>">Ochrana soukromí</a></li>
</ul> </ul>
<div id="civilized"></div> <div id="civilized"></div>
@ -125,7 +125,7 @@
<div id="tos"></div> <div id="tos"></div>
<h2><a href="tos">Podmínky používání</a></h2> <h2><a href="tos">Podmínky používání</a></h2>
<p> <p>
Ano, právničina je nudná, ale musíme se sami právně chránit &ndash; a také vás a vaše data &ndash; proti nepřátelským právníckám fíglům. Máme svoje <a href="/tos">Podmínky používání</a> popisující vaše (a naše) chování a práva ve vztahu k obsahu, soukromí a zákonům. Pokud chcete používat toto fórum, musíte souhlasit s tím, že budete dodržovat <a href="/tos">tyto podmínky</a>. Ano, právničina je nudná, ale musíme se sami právně chránit &ndash; a také vás a vaše data &ndash; proti nepřátelským právníckám fíglům. Máme svoje <a href="<%=tos_path%>">Podmínky používání</a> popisující vaše (a naše) chování a práva ve vztahu k obsahu, soukromí a zákonům. Pokud chcete používat toto fórum, musíte souhlasit s tím, že budete dodržovat <a href="<%=tos_path%>">tyto podmínky</a>.
</p> </p>
<div class="more"> <div class="more">
</div> </div>

View file

@ -1,7 +1,7 @@
<ul class="nav-pills"> <ul class="nav-pills">
<li><a class="active" href="/faq">FAQ</a></li> <li><a class="active" href="<%=faq_path%>">FAQ</a></li>
<li><a href="/tos">Terms of Service</a></li> <li><a href="<%=tos_path%>">Terms of Service</a></li>
<li><a href="/privacy">Privacy</a></li> <li><a href="<%=privacy_path%>">Privacy</a></li>
</ul> </ul>
<div id="civilized"></div> <div id="civilized"></div>
@ -125,7 +125,7 @@
<div id="tos"></div> <div id="tos"></div>
<h2><a href="tos">Terms of Service</a></h2> <h2><a href="tos">Terms of Service</a></h2>
<p> <p>
Yes, legalese is boring, but we must protect ourselves &ndash; and by extension, you and your data &ndash; against unfriendly folks. We have a <a href="/tos">Terms of Service</a> describing your (and our) behavior and rights related to content, privacy, and laws. To use this service, you must agree to abide by our <a href="/tos">TOS</a>. Yes, legalese is boring, but we must protect ourselves &ndash; and by extension, you and your data &ndash; against unfriendly folks. We have a <a href="<%=tos_path%>">Terms of Service</a> describing your (and our) behavior and rights related to content, privacy, and laws. To use this service, you must agree to abide by our <a href="<%=tos_path%>">TOS</a>.
</p> </p>
<div class="more"> <div class="more">
</div> </div>

View file

@ -1,7 +1,7 @@
<ul class="nav-pills"> <ul class="nav-pills">
<li><a href="/faq">FAQ</a></li> <li><a href="<%=faq_path%>">FAQ</a></li>
<li><a href="/tos">Podmínky používání</a></li> <li><a href="<%=tos_path%>">Podmínky používání</a></li>
<li><a class="active" href="/privacy">Ochrana soukromí</a></li> <li><a class="active" href="<%=privacy_path%>">Ochrana soukromí</a></li>
</ul> </ul>
<div id="collect"></div> <div id="collect"></div>

View file

@ -1,7 +1,7 @@
<ul class="nav-pills"> <ul class="nav-pills">
<li><a href="/faq">FAQ</a></li> <li><a href="<%=faq_path%>">FAQ</a></li>
<li><a href="/tos">Terms of Service</a></li> <li><a href="<%=tos_path%>">Terms of Service</a></li>
<li><a class="active" href="/privacy">Privacy</a></li> <li><a class="active" href="<%=privacy_path%>">Privacy</a></li>
</ul> </ul>
<div id="collect"></div> <div id="collect"></div>

View file

@ -1,11 +1,11 @@
<ul class="nav-pills"> <ul class="nav-pills">
<li><a href="/faq">FAQ</a></li> <li><a href="<%=faq_path%>">FAQ</a></li>
<li><a class="active" href="/tos">Podmínky používání</a></li> <li><a class="active" href="<%=tos_path%>">Podmínky používání</a></li>
<li><a href="/privacy">Ochrana soukromí</a></li> <li><a href="<%=privacy_path%>">Ochrana soukromí</a></li>
</ul> </ul>
<p> <p>
The following terms and conditions govern all use of the <%= SiteSetting.company_domain %> website and all content, services and products available at or through the website, including, but not limited to, <%= SiteSetting.company_domain %> Forum Software, <%= SiteSetting.company_domain %> Support Forums and the <%= SiteSetting.company_domain %> Hosting service (“Hosting”), (taken together, the Website). The Website is owned and operated by <%= SiteSetting.company_full_name %> (“<%= SiteSetting.company_short_name %>”). The Website is offered subject to your acceptance without modification of all of the terms and conditions contained herein and all other operating rules, policies (including, without limitation, <%= SiteSetting.company_domain %>s <a href="/privacy">Privacy Policy</a> and <a href="/faq">Community Guidelines</a>) and procedures that may be published from time to time on this Site by <%= SiteSetting.company_short_name %> (collectively, the “Agreement”). The following terms and conditions govern all use of the <%= SiteSetting.company_domain %> website and all content, services and products available at or through the website, including, but not limited to, <%= SiteSetting.company_domain %> Forum Software, <%= SiteSetting.company_domain %> Support Forums and the <%= SiteSetting.company_domain %> Hosting service (“Hosting”), (taken together, the Website). The Website is owned and operated by <%= SiteSetting.company_full_name %> (“<%= SiteSetting.company_short_name %>”). The Website is offered subject to your acceptance without modification of all of the terms and conditions contained herein and all other operating rules, policies (including, without limitation, <%= SiteSetting.company_domain %>s <a href="<%=privacy_path%>">Privacy Policy</a> and <a href="<%=faq_path%>">Community Guidelines</a>) and procedures that may be published from time to time on this Site by <%= SiteSetting.company_short_name %> (collectively, the “Agreement”).
</p> </p>
<p> <p>
@ -122,7 +122,7 @@
<div id="16"></div> <div id="16"></div>
<h2><a href="#16">16. General Representation and Warranty</a></h2> <h2><a href="#16">16. General Representation and Warranty</a></h2>
<p> <p>
You represent and warrant that (i) your use of the Website will be in strict accordance with the <%= SiteSetting.company_short_name %> <a href="/privacy">Privacy Policy</a>, <a href="/faq">Community Guidelines</a>, with this Agreement and with all applicable laws and regulations (including without limitation any local laws or regulations in your country, state, city, or other governmental area, regarding online conduct and acceptable content, and including all applicable laws regarding the transmission of technical data exported from the United States or the country in which you reside) and (ii) your use of the Website will not infringe or misappropriate the intellectual property rights of any third party. You represent and warrant that (i) your use of the Website will be in strict accordance with the <%= SiteSetting.company_short_name %> <a href="<%=privacy_path%>">Privacy Policy</a>, <a href="<%=faq_path%>">Community Guidelines</a>, with this Agreement and with all applicable laws and regulations (including without limitation any local laws or regulations in your country, state, city, or other governmental area, regarding online conduct and acceptable content, and including all applicable laws regarding the transmission of technical data exported from the United States or the country in which you reside) and (ii) your use of the Website will not infringe or misappropriate the intellectual property rights of any third party.
</p> </p>
<div id="17"></div> <div id="17"></div>

View file

@ -1,11 +1,11 @@
<ul class="nav-pills"> <ul class="nav-pills">
<li><a href="/faq">FAQ</a></li> <li><a href="<%=faq_path%>">FAQ</a></li>
<li><a class="active" href="/tos">Terms of Service</a></li> <li><a class="active" href="<%=tos_path%>">Terms of Service</a></li>
<li><a href="/privacy">Privacy</a></li> <li><a href="<%=privacy_path%>">Privacy</a></li>
</ul> </ul>
<p> <p>
The following terms and conditions govern all use of the <%= SiteSetting.company_domain %> website and all content, services and products available at or through the website, including, but not limited to, <%= SiteSetting.company_domain %> Forum Software, <%= SiteSetting.company_domain %> Support Forums and the <%= SiteSetting.company_domain %> Hosting service (“Hosting”), (taken together, the Website). The Website is owned and operated by <%= SiteSetting.company_full_name %> (“<%= SiteSetting.company_short_name %>”). The Website is offered subject to your acceptance without modification of all of the terms and conditions contained herein and all other operating rules, policies (including, without limitation, <%= SiteSetting.company_domain %>s <a href="/privacy">Privacy Policy</a> and <a href="/faq">Community Guidelines</a>) and procedures that may be published from time to time on this Site by <%= SiteSetting.company_short_name %> (collectively, the “Agreement”). The following terms and conditions govern all use of the <%= SiteSetting.company_domain %> website and all content, services and products available at or through the website, including, but not limited to, <%= SiteSetting.company_domain %> Forum Software, <%= SiteSetting.company_domain %> Support Forums and the <%= SiteSetting.company_domain %> Hosting service (“Hosting”), (taken together, the Website). The Website is owned and operated by <%= SiteSetting.company_full_name %> (“<%= SiteSetting.company_short_name %>”). The Website is offered subject to your acceptance without modification of all of the terms and conditions contained herein and all other operating rules, policies (including, without limitation, <%= SiteSetting.company_domain %>s <a href="<%=privacy_path%>">Privacy Policy</a> and <a href="<%=faq_path%>">Community Guidelines</a>) and procedures that may be published from time to time on this Site by <%= SiteSetting.company_short_name %> (collectively, the “Agreement”).
</p> </p>
<p> <p>
@ -122,7 +122,7 @@ In no event will <%= SiteSetting.company_short_name %>, or its suppliers or lice
<div id="16"></div> <div id="16"></div>
<h2><a href="#16">16. General Representation and Warranty</a></h2> <h2><a href="#16">16. General Representation and Warranty</a></h2>
<p> <p>
You represent and warrant that (i) your use of the Website will be in strict accordance with the <%= SiteSetting.company_short_name %> <a href="/privacy">Privacy Policy</a>, <a href="/faq">Community Guidelines</a>, with this Agreement and with all applicable laws and regulations (including without limitation any local laws or regulations in your country, state, city, or other governmental area, regarding online conduct and acceptable content, and including all applicable laws regarding the transmission of technical data exported from the United States or the country in which you reside) and (ii) your use of the Website will not infringe or misappropriate the intellectual property rights of any third party. You represent and warrant that (i) your use of the Website will be in strict accordance with the <%= SiteSetting.company_short_name %> <a href="<%=privacy_path%>">Privacy Policy</a>, <a href="<%=faq_path%>">Community Guidelines</a>, with this Agreement and with all applicable laws and regulations (including without limitation any local laws or regulations in your country, state, city, or other governmental area, regarding online conduct and acceptable content, and including all applicable laws regarding the transmission of technical data exported from the United States or the country in which you reside) and (ii) your use of the Website will not infringe or misappropriate the intellectual property rights of any third party.
</p> </p>
<div id="17"></div> <div id="17"></div>

View file

@ -18,6 +18,14 @@ module Discourse
RailsMultisite::ConnectionManagement.current_hostname RailsMultisite::ConnectionManagement.current_hostname
end end
def self.base_uri
if !ActionController::Base.config.relative_url_root.blank?
return ActionController::Base.config.relative_url_root
else
return ""
end
end
def self.base_url def self.base_url
protocol = "http" protocol = "http"
protocol = "https" if SiteSetting.use_ssl? protocol = "https" if SiteSetting.use_ssl?
@ -27,6 +35,7 @@ module Discourse
result = "#{protocol}://#{current_hostname}" result = "#{protocol}://#{current_hostname}"
end end
result << ":#{SiteSetting.port}" if SiteSetting.port.present? && SiteSetting.port.to_i > 0 result << ":#{SiteSetting.port}" if SiteSetting.port.present? && SiteSetting.port.to_i > 0
result << ActionController::Base.config.relative_url_root if !ActionController::Base.config.relative_url_root.blank?
result result
end end

View file

@ -120,6 +120,7 @@ module PrettyText
# we need to do this to work in a multi site environment, many sites, many settings # we need to do this to work in a multi site environment, many sites, many settings
v8.eval("Discourse.SiteSettings = #{SiteSetting.client_settings_json};") v8.eval("Discourse.SiteSettings = #{SiteSetting.client_settings_json};")
v8.eval("Discourse.BaseUrl = 'http://#{RailsMultisite::ConnectionManagement.current_hostname}';") v8.eval("Discourse.BaseUrl = 'http://#{RailsMultisite::ConnectionManagement.current_hostname}';")
v8.eval("Discourse.getURL = function(url) {return '#{Discourse::base_uri}' + url};")
v8['opts'] = opts || {} v8['opts'] = opts || {}
v8['raw'] = text v8['raw'] = text
v8.eval('opts["mentionLookup"] = function(u){return helpers.is_username_valid(u);}') v8.eval('opts["mentionLookup"] = function(u){return helpers.is_username_valid(u);}')