mirror of
https://github.com/discourse/discourse.git
synced 2024-11-24 00:37:06 +08:00
A mucher saner API for updating the title of routes, even when nested.
Properly sends the title of the page to google analytics
This commit is contained in:
parent
e8637344c3
commit
5fc150e057
|
@ -1,17 +1,9 @@
|
|||
/**
|
||||
The base admin route
|
||||
|
||||
@class AdminRoute
|
||||
@extends Discourse.Route
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminRoute = Discourse.Route.extend({
|
||||
renderTemplate: function() {
|
||||
this.render('admin/templates/admin');
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
Discourse.set('title', I18n.t('admin_title'));
|
||||
titleToken: function() {
|
||||
return I18n.t('admin_title');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -10,6 +10,7 @@ var DiscourseResolver = require('discourse/ember/resolver').default;
|
|||
|
||||
window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
||||
rootElement: '#main',
|
||||
_docTitle: null,
|
||||
|
||||
getURL: function(url) {
|
||||
// If it's a non relative URL, return it.
|
||||
|
@ -25,13 +26,8 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
|
||||
Resolver: DiscourseResolver,
|
||||
|
||||
titleChanged: function() {
|
||||
var title = "";
|
||||
|
||||
if (this.get('title')) {
|
||||
title += "" + (this.get('title')) + " - ";
|
||||
}
|
||||
title += Discourse.SiteSettings.title;
|
||||
_titleChanged: function() {
|
||||
var title = this.get('_docTitle') || Discourse.SiteSettings.title;
|
||||
|
||||
// if we change this we can trigger changes on document.title
|
||||
// only set if changed.
|
||||
|
@ -44,14 +40,14 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
|
|||
title = "(" + notifyCount + ") " + title;
|
||||
}
|
||||
|
||||
if(title !== document.title) {
|
||||
if (title !== document.title) {
|
||||
// chrome bug workaround see: http://stackoverflow.com/questions/2952384/changing-the-window-title-when-focussing-the-window-doesnt-work-in-chrome
|
||||
window.setTimeout(function() {
|
||||
document.title = ".";
|
||||
document.title = title;
|
||||
}, 200);
|
||||
}
|
||||
}.observes('title', 'hasFocus', 'notifyCount'),
|
||||
}.observes('_docTitle', 'hasFocus', 'notifyCount'),
|
||||
|
||||
faviconChanged: function() {
|
||||
if(Discourse.User.currentProp('dynamic_favicon')) {
|
||||
|
|
|
@ -11,11 +11,21 @@ export default ObjectController.extend(Discourse.SelectedPostsCount, {
|
|||
|
||||
maxTitleLength: Discourse.computed.setting('max_topic_title_length'),
|
||||
|
||||
contextChanged: function(){
|
||||
contextChanged: function() {
|
||||
this.set('controllers.search.searchContext', this.get('model.searchContext'));
|
||||
}.observes('topic'),
|
||||
|
||||
termChanged: function(){
|
||||
_titleChanged: function() {
|
||||
var title = this.get('title');
|
||||
if (!Em.empty(title)) {
|
||||
|
||||
// Note normally you don't have to trigger this, but topic titles can be updated
|
||||
// and are sometimes lazily loaded.
|
||||
this.send('refreshTitle');
|
||||
}
|
||||
}.observes('title'),
|
||||
|
||||
termChanged: function() {
|
||||
var dropdown = this.get('controllers.header.visibleDropdown');
|
||||
var term = this.get('controllers.search.term');
|
||||
|
||||
|
|
|
@ -12,16 +12,18 @@ export default {
|
|||
// Out of the box, Discourse tries to track google analytics
|
||||
// if it is present
|
||||
if (typeof window._gaq !== 'undefined') {
|
||||
pageTracker.on('change', function() {
|
||||
window._gaq.push(['_trackPageview', window.location.pathname+window.location.search]);
|
||||
pageTracker.on('change', function(url, title) {
|
||||
window._gaq.push(["_set", "title", title]);
|
||||
window._gaq.push(['_trackPageview', url]);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Also use Universal Analytics if it is present
|
||||
if (typeof window.ga !== 'undefined') {
|
||||
pageTracker.on('change', function() {
|
||||
window.ga('send', 'pageview', window.location.pathname+window.location.search);
|
||||
pageTracker.on('change', function(url, title) {
|
||||
window.ga('send', 'pageview', {page: url, title: title});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ Discourse.PageTracker = Ember.Object.extend(Ember.Evented, {
|
|||
self = this;
|
||||
|
||||
router.on('didTransition', function() {
|
||||
var router = this;
|
||||
self.trigger('change', router.get('url'));
|
||||
this.send('refreshTitle');
|
||||
self.trigger('change', this.get('url'), Discourse.get('_docTitle'));
|
||||
});
|
||||
this.set('started', true);
|
||||
}
|
||||
|
|
|
@ -5,9 +5,7 @@ export default Discourse.Route.extend({
|
|||
});
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
controller.set('model', model);
|
||||
Discourse.set('title', I18n.t('about.simple_title'));
|
||||
titleToken: function() {
|
||||
return I18n.t('about.simple_title');
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
var ApplicationRoute = Em.Route.extend({
|
||||
|
||||
siteTitle: Discourse.computed.setting('title'),
|
||||
|
||||
actions: {
|
||||
_collectTitleTokens: function(tokens) {
|
||||
tokens.push(this.get('siteTitle'));
|
||||
Discourse.set('_docTitle', tokens.join(' - '));
|
||||
},
|
||||
|
||||
showTopicEntrance: function(data) {
|
||||
this.controllerFor('topic-entrance').send('show', data);
|
||||
},
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
export default Discourse.Route.extend({
|
||||
|
||||
model: function() {
|
||||
if (PreloadStore.get('badges')) {
|
||||
return PreloadStore.getAndRemove('badges').then(function(json) {
|
||||
|
@ -10,8 +9,7 @@ export default Discourse.Route.extend({
|
|||
}
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
controller.set('model', model);
|
||||
Discourse.set('title', I18n.t('badges.title'));
|
||||
titleToken: function() {
|
||||
return I18n.t('badges.title');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export default Ember.Route.extend({
|
||||
export default Discourse.Route.extend({
|
||||
serialize: function(model) {
|
||||
return {id: model.get('id'), slug: model.get('name').replace(/[^A-Za-z0-9_]+/g, '-').toLowerCase()};
|
||||
},
|
||||
|
@ -13,12 +13,18 @@ export default Ember.Route.extend({
|
|||
}
|
||||
},
|
||||
|
||||
titleToken: function() {
|
||||
var model = this.modelFor('badges.show');
|
||||
if (model) {
|
||||
return model.get('displayName');
|
||||
}
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
Discourse.UserBadge.findByBadgeId(model.get('id')).then(function(userBadges) {
|
||||
controller.set('userBadges', userBadges);
|
||||
controller.set('userBadgesLoaded', true);
|
||||
});
|
||||
controller.set('model', model);
|
||||
Discourse.set('title', model.get('displayName'));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -61,13 +61,17 @@ export default function(filter, params) {
|
|||
});
|
||||
},
|
||||
|
||||
titleToken: function() {
|
||||
var filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0}),
|
||||
model = this.currentModel;
|
||||
|
||||
return I18n.t('filters.with_category', { filter: filterText, category: model.get('name') });
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
var topics = this.get('topics'),
|
||||
periods = this.controllerFor('discovery').get('periods'),
|
||||
periodId = topics.get('for_period') || (filter.indexOf('/') > 0 ? filter.split('/')[1] : ''),
|
||||
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
|
||||
|
||||
Discourse.set('title', I18n.t('filters.with_category', { filter: filterText, category: model.get('name') }));
|
||||
periodId = topics.get('for_period') || (filter.indexOf('/') > 0 ? filter.split('/')[1] : '');
|
||||
|
||||
this.controllerFor('navigation/category').set('canCreateTopic', topics.get('can_create_topic'));
|
||||
this.controllerFor('discovery/topics').setProperties({
|
||||
|
|
|
@ -32,6 +32,13 @@ export default function(filter, extras) {
|
|||
return Discourse.TopicList.list(filter, findOpts, extras);
|
||||
},
|
||||
|
||||
titleToken: function() {
|
||||
if (filter === Discourse.Utilities.defaultHomepage()) { return; }
|
||||
|
||||
var filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
|
||||
return I18n.t('filters.with_topics', {filter: filterText});
|
||||
},
|
||||
|
||||
setupController: function(controller, model, trans) {
|
||||
|
||||
controller.setProperties(Em.getProperties(trans, _.keys(queryParams).map(function(v){
|
||||
|
@ -39,14 +46,7 @@ export default function(filter, extras) {
|
|||
})));
|
||||
|
||||
var periods = this.controllerFor('discovery').get('periods'),
|
||||
periodId = model.get('for_period') || (filter.indexOf('/') > 0 ? filter.split('/')[1] : ''),
|
||||
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
|
||||
|
||||
if (filter === Discourse.Utilities.defaultHomepage()) {
|
||||
Discourse.set('title', '');
|
||||
} else {
|
||||
Discourse.set('title', I18n.t('filters.with_topics', {filter: filterText}));
|
||||
}
|
||||
periodId = model.get('for_period') || (filter.indexOf('/') > 0 ? filter.split('/')[1] : '');
|
||||
|
||||
this.controllerFor('discovery/topics').setProperties({
|
||||
model: model,
|
||||
|
|
|
@ -21,6 +21,29 @@ Discourse.Route = Em.Route.extend({
|
|||
Em.run.scheduleOnce('afterRender', Discourse.Route, 'cleanDOM');
|
||||
},
|
||||
|
||||
actions: {
|
||||
_collectTitleTokens: function(tokens) {
|
||||
// If there's a title token method, call it and get the token
|
||||
if (this.titleToken) {
|
||||
var t = this.titleToken();
|
||||
if (t && t.length) {
|
||||
if (t instanceof Array) {
|
||||
t.forEach(function(ti) {
|
||||
tokens.push(ti);
|
||||
});
|
||||
} else {
|
||||
tokens.push(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
refreshTitle: function() {
|
||||
this.send('_collectTitleTokens', []);
|
||||
}
|
||||
},
|
||||
|
||||
redirectIfLoginRequired: function() {
|
||||
var app = this.controllerFor('application');
|
||||
if (app.get('loginRequired')) {
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
/**
|
||||
The route for handling the "Categories" view
|
||||
|
||||
@class DiscoveryCategoriesRoute
|
||||
@extends Discourse.Route
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.DiscoveryCategoriesRoute = Discourse.Route.extend(Discourse.OpenComposer, {
|
||||
renderTemplate: function() {
|
||||
this.render('navigation/categories', { outlet: 'navigation-bar' });
|
||||
|
@ -31,16 +23,18 @@ Discourse.DiscoveryCategoriesRoute = Discourse.Route.extend(Discourse.OpenCompos
|
|||
});
|
||||
},
|
||||
|
||||
titleToken: function() {
|
||||
return I18n.t('filters.categories.title');
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
controller.set('model', model);
|
||||
Discourse.set('title', I18n.t('filters.categories.title'));
|
||||
|
||||
// Only show either the Create Category or Create Topic button
|
||||
this.controllerFor('navigation/categories').set('canCreateCategory', model.get('can_create_category'));
|
||||
this.controllerFor('navigation/categories').set('canCreateTopic', model.get('can_create_topic') && !model.get('can_create_category'));
|
||||
|
||||
this.openTopicDraft(model);
|
||||
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
|
|
@ -12,7 +12,15 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||
show_deleted: { replace: true }
|
||||
},
|
||||
|
||||
titleToken: function() {
|
||||
var model = this.modelFor('topic');
|
||||
if (model) {
|
||||
return model.get('title');
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
||||
showTopicAdminMenu: function() {
|
||||
this.controllerFor("topic-admin-menu").send("show");
|
||||
},
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
export default Discourse.Route.extend({
|
||||
|
||||
titleToken: function() {
|
||||
var model = this.modelFor('user');
|
||||
var username = model.get('username');
|
||||
if (username) {
|
||||
return [I18n.t("user.profile"), username];
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
logout: function() {
|
||||
Discourse.logout();
|
||||
|
|
|
@ -17,11 +17,6 @@ export default Discourse.View.extend(AddCategoryClass, Discourse.Scrolling, {
|
|||
|
||||
postStream: Em.computed.alias('controller.postStream'),
|
||||
|
||||
_updateTitle: function() {
|
||||
var title = this.get('topic.title');
|
||||
if (title) return Discourse.set('title', _.unescape(title));
|
||||
}.observes('topic.loaded', 'topic.title'),
|
||||
|
||||
_composeChanged: function() {
|
||||
var composerController = Discourse.get('router.composerController');
|
||||
composerController.clearState();
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
export default Ember.View.extend(Discourse.ScrollTop, {
|
||||
templateName: 'user/user',
|
||||
userBinding: 'controller.content',
|
||||
|
||||
updateTitle: function() {
|
||||
var username = this.get('user.username');
|
||||
if (username) {
|
||||
Discourse.set('title', "" + (I18n.t("user.profile")) + " - " + username);
|
||||
}
|
||||
}.observes('user.loaded', 'user.username')
|
||||
userBinding: 'controller.content'
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user